您的位置:首页 > 其它

BZOJ 1018: [SHOI2008]堵塞的交通traffic

2017-12-26 21:02 274 查看
线段树有这种姿势啊。。是我太菜了。。。

一开始简直被吓呆了,总感觉要写好多。。很烦。。。对着某个题解盯了半天才敢写QAQ

然后我发现很赞啊

幸好发现了这篇233 参考了他的写法 (我基本上是抄他的

用一个数组a[i][j],维护从x节点最左端的i行能否到最右端的j行。

另一个数组v[i],v[0]表示x节点最右端的点能不能从右面绕到另外一行。v[1]代表最左端的点能不能从左面绕到另外一行。

转移大概就是各种讨论吧,画画图什么的….

然后我就在2k左右的代码就解决这题啦~ 时间也很可观

大家也可以参考参考我的代码QAQ,写的短的感觉真不错233

#include<bits/stdc++.h>
using namespace std;
const int N=4e5+3,inf=1e9+7;
inline int read(){
int x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
return x*f;
}
struct mt{bool a[2][2],v[2];}s
; int n;
mt upd(mt s1,mt s2,bool b[]){
mt g;
for(int i=0;i<2;++i)for(int j=0;j<2;++j)
g.a[i][j]= s1.a[i][0] && b[0] && s2.a[0][j] || s1.a[i][1] && b[1] && s2.a[1][j];
g.v[0]=s1.v[0] || s1.a[0][0] && b[0] && s2.v[0] && s1.a[1][1] && b[1];
g.v[1]=s2.v[1] || s2.a[0][0] && b[0] && s1.v[1] && s2.a[1][1] && b[1];
return g;
}
bool b
[2]; int X1,Y1,X2,Y2;
mt access(int x,int l,int r,int ql,int qr){
if(l==ql && r==qr) return s[x];
int mid=l+r>>1;
if(qr<=mid) return access(x<<1,l,mid,ql,qr);
if(ql>mid) return access(x<<1|1,mid+1,r,ql,qr);
return upd(access(x<<1,l,mid,ql,mid),access(x<<1|1,mid+1,r,mid+1,qr),b[x]);
}
void bulid(int x,int l,int r){
if(l==r) s[x].a[0][0]=s[x].a[1][1]=1;
else {int mid=l+r>>1; bulid(x<<1,l,mid),bulid(x<<1|1,mid+1,r);}
}
void change(int x,int l,int r,int u){
int mid=l+r>>1,lc=x<<1,rc=lc|1;
if(X1==X2 && Y1==mid){
b[x][X1]=u; s[x]=upd(s[lc],s[rc],b[x]);
}
else if(l==r) s[x].a[0][1]=s[x].a[1][0]=s[x].v[0]=s[x].v[1]=u;
else{
if(Y2<=mid) change(lc,l,mid,u); else change(rc,mid+1,r,u);
s[x]=upd(s[lc],s[rc],b[x]);
}
}
void ask(){
mt L=access(1,1,n,1,Y1),R=access(1,1,n,Y2,n),M=access(1,1,n,Y1,Y2);
bool g=0;
for(int i=0;i<2;++i)for(int j=0;j<2;++j)
if(M.a[i][j] && (i==X1||L.v[1]) && (j==X2||R.v[0])){g=1; break;}
puts(g?"Y":"N");
}
int main(){
n=read(); bulid(1,1,n);
while(1){
char c[10]; scanf("%s",c);
if(c[0]=='E')return 0;
X1=read()-1,Y1=read(),X2=read()-1,Y2=read();
if(Y1>Y2) swap(X1,X2),swap(Y1,Y2);
if(c[0]=='A') ask();
else change(1,1,n,c[0]=='O');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: