您的位置:首页 > 其它

BZOJ1018: [SHOI2008]堵塞的交通traffic

2017-09-02 23:52 302 查看

BZOJ1018: [SHOI2008]堵塞的交通traffic

线段树 的 奇妙世界

题解:

直接%PoPoQQQ:http://blog.csdn.net/popoqqq/article/details/44116729

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
//#define D(x) cout<<#x<<" = "<<x<<"  "
//#define E cout<<endl
#define D(x)
#define E
using namespace std;
const int N = 200005;

int C; bool hang
[2],lie
;

struct Data{
bool a[2][2];
Data(){ a[0][0]=a[0][1]=a[1][0]=a[1][1]=false; }
Data(bool op){ a[0][0]=a[1][1]=true; a[0][1]=a[1][0]=op; }
bool * operator [] (int x){ return a[x]; }
};
Data merge(bool sta[2],Data x,Data y){
Data res;
res[0][0]=(sta[0]&x[0][0]&y[0][0])|(sta[1]&x[0][1]&y[1][0]);
res[1][1]=(sta[0]&x[1][0]&y[0][1])|(sta[1]&x[1][1]&y[1][1]);
res[0][1]=(sta[0]&x[0][0]&y[0][1])|(sta[1]&x[0][1]&y[1][1]);
res[1][0]=(sta[0]&x[1][0]&y[0][0])|(sta[1]&x[1][1]&y[1][0]);
return res;
}

struct Node{
int l,r; Data d;
} pool[N*4];

void dfs(int x){
Node &t=pool[x];
D(t.l); D(t.r); E;
D(t.d[0][0]); D(t.d[0][1]); D(t.d[1][0]); D(t.d[1][1]); E;
if(t.l!=t.r){
dfs(x*2); dfs(x*2+1);
}
}

void update(int x){
Node &t=pool[x];
int mid=(t.l+t.r)>>1;
t.d=merge(hang[mid],pool[x*2].d,pool[x*2+1].d);
}

void build(int x,int l,int r){
Node &t=pool[x];
t.l=l; t.r=r;
if(l!=r){
int mid=(l+r)>>1;
build(x*2,l,mid);
build(x*2+1,mid+1,r);
}
else t.d=Data(false);
}

void change_hang(int x,int lp,int k,int op){
Node &t=pool[x];
int mid=(t.l+t.r)>>1;
if(mid==lp){
hang[lp][k]=op;
}
else{
if(lp<mid)change_hang(x*2,lp,k,op);
else change_hang(x*2+1,lp,k,op);
}
update(x);
}

void change_lie(int x,int p,int op){
Node &t=pool[x];
if(t.l==t.r){
lie[p]=op;
t.d=Data(lie[p]);
}
else{
int mid=(t.l+t.r)>>1;
if(p<=mid)change_lie(x*2,p,op);
else change_lie(x*2+1,p,op);
update(x);
}
}

void _get_left(int x,int &pos,Data &d,int k){
Node &t=pool[x];
if(t.l==t.r) return;
int mid=(t.l+t.r)>>1;
Data rd=pool[x*2+1].d;
Data tp=merge(hang[t.r],rd,d);
if(tp[0][k] || tp[1][k]){
pos=mid+1; d=tp; _get_left(x*2,pos,d,k);
}
else _get_left(x*2+1,pos,d,k);
}

void getLeft(int x,int &pos,Data &d,int k){
Node &t=pool[x];
if(t.l==t.r) return;
int mid=(t.l+t.r)>>1;
if(pos<=mid) getLeft(x*2,pos,d,k);
else{
getLeft(x*2+1,pos,d,k);
if(pos!=mid+1) return;
Data tp=merge(hang[mid],pool[x*2].d,d);
if(tp[0][k] || tp[1][k]){ pos=t.l; d=tp; }
else _get_left(x*2,pos,d,k);
}
}

void _get_right(int x,int &pos,Data &d,int k){
Node &t=pool[x];
if(t.l==t.r) return;
int mid=(t.l+t.r)>>1;
Data ld=pool[x*2].d;
Data tp=merge(hang[t.l-1],d,ld);
if(tp[k][0] || tp[k][1]){
pos=mid; d=tp; _get_right(x*2+1,pos,d,k);
}
else _get_right(x*2,pos,d,k);
}

void getRight(int x,int &pos,Data &d,int k){
Node &t=pool[x];
if(t.l==t.r) return;
int mid=(t.l+t.r)>>1;
if(pos>mid) getRight(x*2+1,pos,d,k);
else{
getRight(x*2,pos,d,k);
if(pos!=mid) return;
Data tp=merge(hang[mid],d,pool[x*2+1].d);
if(tp[k][0] || tp[k][1]){ pos=t.r; d=tp; }
else _get_right(x*2+1,pos,d,k);
}
}

Data getAns(int x,int ql,int qr){
Node &t=pool[x];
//  D(x); D(t.l); D(t.r); D(ql); D(qr); E;
if(t.l==ql && t.r==qr) return t.d;
int mid=(t.l+t.r)>>1;
if(qr<=mid) return getAns(x*2,ql,qr);
if(ql>mid) return getAns(x*2+1,ql,qr);
return merge(hang[mid],getAns(x*2,ql,mid),getAns(x*2+1,mid+1,qr));
}

void solve(int x1,int y1,int x2,int y2){
Data tp;

tp=Data(lie[y1]);
getLeft(1,y1,tp,x1-1);
x1=tp[0][x1-1]?1:2;

tp=Data(lie[y2]);
getRight(1,y2,tp,x2-1);
x2=tp[x2-1][0]?1:2;

D(x1);D(y1); D(x2);D(y2); E;
tp=getAns(1,y1,y2);
if(tp[x1-1][x2-1]) puts("Y");
else puts("N");
}

int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
char op[15]; int x1,y1,x2,y2;
cin>>C; build(1,1,C);
while(scanf("%s",op)!=EOF && op[0]!='E'){
D(op); E;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(y1>y2) swap(y1,y2), swap(x1,x2);
if(op[0]=='A'){
solve(x1,y1,x2,y2);
}
else{
if(x1==x2){ change_hang(1,y1,x1-1,op[0]=='O'?1:0); }
else{ change_lie(1,y1,op[0]=='O'?1:0); }
//          dfs(1);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: