2017.5.25-5.28 hide捉迷藏 失败总结

来源:互联网 发布:我的世界天堂门js 编辑:程序博客网 时间:2024/05/20 18:47

        被两个zjoi搞得痛不欲生、、


        这个题用线段树做的话,是:

         利用树的dfs序,生成括号序列(化树为链),然后就可以利用区间结构维护了


        


匹配完之后一定都是“))((”的形式。这样区间ans就可以表达为:在左边的,在右边的,在两边的

  所以就要做好衔接点的维护:


那么怎么判断那个点是黑点?

其实不用判断,只用考虑黑点与白点怎么合并就行了、

白点的所有要维护的值都为-INF,但C2、C5为0,这就是说括号可以传递,但最优值不能传递(这样最优值就不会选这个点的信息)

黑点所有要维护的值都为0,这样它就可以参与括号之间的转移,最优值的信息往上走也就会经历筛选。




但要注意:up十分难写,一个地方错了就炸了。

                还要注意数组开的大小


   而且,读入时要注意:ch!=\r   !!\r!!!!   \r  !!!!一定是\r!!!!!


码:

#include<iostream>#include<cstdio>#include<vector>using namespace std;#define N 100005#define zuo o<<1,l,mid#define you o<<1|1,mid+1,r#define INF 1e9vector<int>v[N];int bla,C2[N*12],hb[N],C5[N*12],M25[N*12],L2[N*12],R5[N*12],L25[N*12],R25[N*12],ch[N*3],dui[N*3],op,a,cnt,n,q,i,x,y,z;char str;void up(int now){int l=now<<1;int r=now<<1|1;    if(C2[r]>C5[l]) C2[now]=C2[l]+C2[r]-C5[l] ;else C2[now]=C2[l];if(C2[r]>C5[l]) C5[now]=C5[r];else C5[now]=C5[r]+C5[l]-C2[r];L2[now]=max(L2[l],L2[r]-C2[l]+C5[l]);R5[now]=max(R5[r],R5[l]-C5[r]+C2[r]);L25[now]=max(L25[l],max(C2[l]-C5[l]+L25[r],C2[l]+C5[l]+L2[r]));R25[now]=max(R25[r],max(C5[r]-C2[r]+R25[l],C2[r]+C5[r]+R5[l]));M25[now]=max(max(M25[l],M25[r]),max(R5[l]+L25[r],L2[r]+R25[l]));}void jian(int o,int l,int r){if(l==r){ M25[o] = -INF;if(ch[l]==-2){C2[o]=1;L25[o] = R25[o] = L2[o] = R5[o] =-INF;}else if(ch[l]==-5){C5[o]=1;L25[o] = R25[o] = L2[o] = R5[o] =-INF;} else {bla++;L25[o] = R25[o] = L2[o] = R5[o] = 0;      }return;}int mid=(l+r)>>1;jian(zuo);jian(you);up(o);}void gai(int o,int l,int r){if(l==r){    if(op==1){L25[o] = R25[o] = L2[o] = R5[o] = -INF;}else{L25[o] = R25[o] = L2[o] = R5[o] = 0;}return; }int mid=(l+r)>>1;if(a<=mid)gai(zuo);else gai(you);up(o);}void dfs(int now,int fu){ch[++cnt]=-5;ch[++cnt]=now;dui[now]=cnt;for(int i=0;i<v[now].size();i++){if(v[now][i]==fu)continue;dfs(v[now][i],now);    }  ch[++cnt]=-2;}int main(){scanf("%d",&n);for(i=1;i<n;i++){scanf("%d%d",&x,&y);v[x].push_back(y);v[y].push_back(x);}dfs(1,0);jian(1,1,cnt);//for(i=1;i<=cnt;i++)//if(ch[i]==-2)cout<<')';else if(ch[i]==-5)cout<<"(";else cout<<ch[i];//cout<<endl;scanf("%d",&q);for(i=1;i<=q;i++){scanf("%c",&str);while(str=='\n'||str=='\0'||str=='\r')scanf("%c",&str);if(str=='G'){if(bla==0)printf("-1\n");  else if(bla==1)printf("0\n");  else printf("%d\n",M25[1]);}else  {  scanf("%d",&z);  if(hb[z]==0)  {bla--;  hb[z]=1;  op=1;  a=dui[z];  gai(1,1,cnt);}else   {bla++;  hb[z]=0;  op=0;  a=dui[z];  gai(1,1,cnt);  }  }}}


原创粉丝点击