2017.6.23 染色 思考记录

来源:互联网 发布:ubuntu 开机执行脚本 编辑:程序博客网 时间:2024/05/20 00:12

其实没什么难的,关键就是细节很重要、


注意树链剖分跳重链时是要手动判断top和top的父亲的、

另外work的时候用dui【】操作。、、、、


码:

#include<iostream>#include<cstdio>#include<vector>using namespace std;#define zuo o<<1,l,mid#define you o<<1|1,mid+1,r#define N 200005vector<int>v[N];int d[N],fu[N],op,sz[N],ans,woc[N],ys[N],n,m,he[N<<2],rs[N<<2],zys[N<<2],yys[N<<2],i,x,y,a,b,c,hson[N],dui[N],top[N],tot,lys,rys;char ch; void dfs1(int now,int fa,int shen){d[now]=shen;fu[now]=fa;sz[now]=1;for(int i=0;i<v[now].size();i++){int nd=v[now][i];if(nd==fa)continue;dfs1(nd,now,shen+1);sz[now]+=sz[nd];if(sz[hson[now]]<sz[nd])hson[now]=nd;}}void dfs2(int now,int tap){top[now]=tap;dui[now]=++tot;ys[tot]=woc[now];//yys[tot]=ys[now];if(hson[now]!=0)dfs2(hson[now],tap);for(int i=0;i<v[now].size();i++){int nd=v[now][i];if(nd==fu[now]||nd==hson[now])continue;dfs2(nd,nd);}}void up(int o){int ll=o<<1;int rr=o<<1|1;he[o]=he[ll]+he[rr];zys[o]=zys[ll];yys[o]=yys[rr];if(zys[rr]==yys[ll])he[o]--;}void down(int o){int ll=o<<1;int rr=o<<1|1;if(rs[o]!=-1){he[ll]=1;he[rr]=1;rs[ll]=rs[o];rs[rr]=rs[o];zys[ll]=rs[o];yys[ll]=rs[o];zys[rr]=rs[o];yys[rr]=rs[o];rs[o]=-1;}}void jian(int o,int l,int r){rs[o]=-1;if(l==r){  he[o]=1;  zys[o]=ys[l];  yys[o]=ys[l];return;}int mid=(l+r)>>1;jian(zuo);jian(you);up(o);}void gai(int o,int l,int r){if(a<=l&&b>=r){if(op==1){he[o]=1;rs[o]=c;zys[o]=c;yys[o]=c;}if(op==2){ans+=he[o];   if(lys==-1)lys=zys[o];   else   {   if(rys==zys[o])--ans;      }rys=yys[o];}if(op==3){if(yys[o]==lys)--ans;lys=-1;}return;}down(o);int mid=(l+r)>>1;if(a<=mid)gai(zuo);if(b>mid)gai(you);up(o);}void work(int x,int y){ans=0;lys=-1;rys=-1;while(top[x]!=top[y]){if(d[top[x]]>d[top[y]])swap(x,y);   if(op==1)   {   a=dui[top[y]];   b=dui[y];   gai(1,1,tot);      }else   {   a=dui[top[y]];   b=dui[y];   gai(1,1,tot);   op=3;   a=dui[fu[top[y]]];   b=dui[fu[top[y]]];   gai(1,1,tot);             op=2;   }y=fu[top[y]];}if(d[y]<d[x])swap(x,y);a=dui[x];b=dui[y];gai(1,1,tot);}int main(){scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%d",&woc[i]);for(i=1;i<n;i++){scanf("%d%d",&x,&y);v[x].push_back(y);v[y].push_back(x);}dfs1(1,1,1);dfs2(1,1);jian(1,1,tot);for(int i=1;i<=m;i++){scanf("%c",&ch);while(ch!='Q'&&ch!='C')scanf("%c",&ch);if(ch=='Q'){scanf("%d%d",&x,&y);op=2;work(x,y);printf("%d\n",ans);}else{scanf("%d%d%d",&x,&y,&c);op=1;work(x,y);}}}

原创粉丝点击