フェイス質問
問題の意味
A \(2 \回nは\)最初にサポートするために必要な、トレリスダイヤグラム空である(M \)\操作、各動作が追加または削除、またはグリッドの一方の側は、二点間通信かどうかを尋ねることができます。
問題の解決策
三辺上の左のボックスの各々は、連続する単位の左上部との間の通信を維持するために、セグメントツリーを有するユニットとして、右上、右の4つの頂点それぞれを下げ、左下。親ノード間の通信は、右の4つの頂点によって得られた、子供の4つの頂点の間の通信動作を介して残すことができます。記録の間の通信は、4つの頂点が必要なので\(6 \)頂部ユニットの通信状態が最大でいるので、ブール変数を(2 6 = 64 ^ \)\種、親ノードがすべての場合に前処理することができます頂点の通信状態。
追加または削除を行う場合、単にリーフノードに対応するエッジを削除し、ルート・ノード・パスの状態上のすべてのノードへの更新。あなたは、横軸を依頼することを望むかもしれないので、要求されたときの二点である\(L、R&LTは\) 、これらは図3分割される:\([1、L]、[L、R&LT]、[R&LT、N-] \ )。特定の質問点が落ちるので、各セグメントツリー頂部の通信状態により決定することができ、\([L、R] \ ) により、容易に、4つの頂点にすることができる([1、L] \ 、[L、R]、[ R、N] \) 状態は問い合わせノード通信か否かを判断する通信の三つの部分を有します。
コード
#include<iostream>
#include<cstdio>
using namespace std;
const int inf=1e9;
const int maxn=1e5+5,maxm=3e5+5;
inline int ls(int u){ return u<<1; }
inline int rs(int u){ return u<<1|1; }
int l[maxm],r[maxm],v[maxm];
int fa[6];
int ff(int u){ return (fa[u]==u)?u:(fa[u]=ff(fa[u])); }
bool flg=true;
inline int calc(int x,int y){
int i,j,z=0;
for (i=0;i<6;i++) fa[i]=i;
for (i=3;i>=0;i--) for (j=3;j>i;j--){
if (x&1) fa[ff(j)]=ff(i); x>>=1;
}
for (i=5;i>=2;i--) for (j=5;j>i;j--){
if (y&1) fa[ff(j)]=ff(i); y>>=1;
}
for (i=0;i<4;i++) for (j=i+1;j<4;j++){
z<<=1; z|=(ff(i<2?i:i+2)==ff(j<2?j:j+2));
}
flg=false;
return z;
}
int mul[1<<6][1<<6];
inline int add(int x,int y){
switch (y){
case 0: return x|0b100000;
case 1: return x|0b010000;
case 2: return x|0b000010;
}
return -1;
}
inline int del(int x,int y){
switch (y){
case 0: return x&0b011111;
case 1: return x&0b101111;
case 2: return x&0b111101;
}
return -1;
}
void build(int u,int _l,int _r){
l[u]=_l; r[u]=_r; v[u]=0;
if (l[u]==r[u]) return;
int _m=(_l+_r)/2;
build(ls(u),_l,_m);
build(rs(u),_m+1,_r);
}
void addedge(int u,int x,int p){
if (l[u]>x||r[u]<x) return;
if (l[u]==r[u]){
v[u]=add(v[u],p); return;
}
addedge(ls(u),x,p);
addedge(rs(u),x,p);
v[u]=mul[v[ls(u)]][v[rs(u)]];
}
void deledge(int u,int x,int p){
if (l[u]>x||r[u]<x) return;
if (l[u]==r[u]){
v[u]=del(v[u],p); return;
}
deledge(ls(u),x,p);
deledge(rs(u),x,p);
v[u]=mul[v[ls(u)]][v[rs(u)]];
}
int query(int u,int _l,int _r){
if (l[u]>_r||r[u]<_l) return 0b010010;
if (l[u]>=_l&&r[u]<=_r) return v[u];
return mul[query(ls(u),_l,_r)][query(rs(u),_l,_r)];
}
char s[10];
int adjust(int &x1,int &y1,int &x2,int &y2){
if (x1>x2){ swap(x1,x2); swap(y1,y2); }
if (y1>y2){ swap(x1,x2); swap(y1,y2); }
if (x1==2) return 2;
if (x2==1) return 1;
return 0;
}
int main(){
int i,j,n;
int x1,y1,x2,y2,t;
int a,b,c;
bool flg;
for (i=0;i<(1<<6);i++) for (j=0;j<(1<<6);j++)
mul[i][j]=calc(i,j);
scanf("%d",&n);
build(1,0,n+2);
flg=true;
while (flg){
scanf("%s",s);
switch (s[0]){
case 'O':
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
t=adjust(x1,y1,x2,y2);
addedge(1,y1,t);
break;
case 'C':
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
t=adjust(x1,y1,x2,y2);
deledge(1,y1,t);
break;
case 'A':
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
adjust(x1,y1,x2,y2);
a=query(1,0,y1-1);
b=query(1,y1,y2-1);
c=query(1,y2,n+2);
if (a&0b000001) b=mul[0b111111][b];
if (c&0b100000) b=mul[b][0b111111];
a=x1-1; c=x2+1;
if (a>c) swap(a,c);
if (a==c) puts("Y");
else switch (a*10+c){
case 01: puts((b&0b100000)?"Y":"N"); break;
case 02: puts((b&0b010000)?"Y":"N"); break;
case 03: puts((b&0b001000)?"Y":"N"); break;
case 12: puts((b&0b000100)?"Y":"N"); break;
case 13: puts((b&0b000010)?"Y":"N"); break;
case 23: puts((b&0b000001)?"Y":"N"); break;
}
break;
case 'E':
flg=false; break;
}
}
return 0;
}