[SDOI2011]染色

杀马特。学长 韩版系。学妹 提交于 2019-11-28 07:51:52

题目描述

输入格式

不只有线段树外的节点需要合并,线段树内相邻节点,也要判合并

#include<bits/stdc++.h>  #define re return  #define inc(i,l,r) for(int i=l;i<=r;++i)    using namespace std;  template<typename T>inline void rd(T&x)  {      char c;bool f=0;      while((c=getchar())<'0'||c>'9')if(c=='-')f=1;      x=c^48;      while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);      if(f)x=-x;  }    const int maxn=100005;   int n,m,tot,ans,k=1;  int size[maxn],son[maxn],top[maxn],fa[maxn],deep[maxn];  int rev[maxn],seg[maxn],col[maxn];  int hd[maxn];    struct node{      int to,nt;  }e[maxn<<1];   inline void add(int x,int y)  {      e[++k].to=y;e[k].nt=hd[x];hd[x]=k;       e[++k].to=x;e[k].nt=hd[y];hd[y]=k;   }    //-------------------------------------------------------------------------------  inline void dfs1(int x)  {      size[x]=1;      deep[x]=deep[fa[x]]+1;      for(int i=hd[x];i;i=e[i].nt)      {          int v=e[i].to;          if(v==fa[x])continue;          fa[v]=x;          dfs1(v);          size[x]+=size[v];          if(size[v]>size[son[x]])              son[x]=v;      }        }    inline void dfs2(int x,int ftop)  {      top[x]=ftop;      seg[x]=++tot;      rev[tot]=x;      if(son[x])          dfs2(son[x],ftop);      for(int i=hd[x];i;i=e[i].nt)      {          int v=e[i].to;          if(!top[v])              dfs2(v,v);      }  }  //----------------------------------------------------------------------------------  #define lson rt<<1  #define rson rt<<1|1  int sum[maxn<<2],lc[maxn<<2],rc[maxn<<2],lazy[maxn<<2];    inline void pushup(int rt)  {      lc[rt]=lc[lson];      rc[rt]=rc[rson];      sum[rt]=sum[lson]+sum[rson]-(rc[lson]==lc[rson]);  }    inline void pushdown(int rt)  {      lazy[lson]=lazy[rson]=1;      sum[lson]=1;sum[rson]=1;      lc[lson]=rc[lson]=lc[rt];      lc[rson]=rc[rson]=rc[rt];      lazy[rt]=0;  }    inline void build(int rt,int l,int r)  {      if(l==r)      {          lc[rt]=rc[rt]=col[rev[l]];          sum[rt]=1;          re ;      }      int mid=(l+r)>>1;      build(lson,l,mid);      build(rson,mid+1,r);      pushup(rt);  }    inline void addd(int rt,int l,int r,int x,int y,int z)  {      if(x<=l&&r<=y)      {          sum[rt]=1;          lazy[rt]=1;          lc[rt]=rc[rt]=z;          re ;      }      if(lazy[rt])pushdown(rt);      int mid=(l+r)>>1;      if(x<=mid)addd(lson,l,mid,x,y,z);      if(y>mid)addd(rson,mid+1,r,x,y,z);      pushup(rt);  }      struct qwq{      int l_col,r_col;  };  inline qwq query(int rt,int l,int r,int x,int y)  {      if(x<=l&&r<=y)      {          ans+=sum[rt];          re (qwq){lc[rt],rc[rt]};      }      int mid=(l+r)>>1;      if(lazy[rt])pushdown(rt);      if(y<=mid)re query(lson,l,mid,x,y);      if(mid<x) re query(rson,mid+1,r,x,y);      else       {          qwq v1=query(lson,l,mid,x,y);          qwq v2=query(rson,mid+1,r,x,y);                    if(v1.r_col==v2.l_col)--ans;                    re (qwq){v1.l_col,v2.r_col};      }  }      int main()  {  //    freopen("in.txt","r",stdin);            int x,y,z;      rd(n),rd(m);      inc(i,1,n)      rd(col[i]);            inc(i,2,n)      {          rd(x),rd(y);          add(x,y);      }            dfs1(1);      dfs2(1,1);      build(1,1,n);                  int cnt=0;      char ss[10];      inc(i,1,m)      {          scanf("%s",ss);          rd(x),rd(y);          if(ss[0]=='Q')          {              ++cnt;              ans=0;                        int lastx=-1,lasty=-1;                    while(top[x]!=top[y])                {                    if(deep[top[x]]<deep[top[y]])                    {                        swap(x,y);                        swap(lastx,lasty);                  }                                qwq    v1=query(1,1,n,seg[top[x]],seg[x]);                  ans-=(lastx==v1.r_col);                  lastx=v1.l_col;                  x=fa[top[x]];              }                            if(deep[x]>deep[y])              {                  swap(x,y);                  swap(lastx,lasty);              }                            qwq v1=query(1,1,n,seg[x],seg[y]);              ans=ans-(lastx==v1.l_col)-(lasty==v1.r_col);              printf("%d\n",ans);          }          else          {               rd(z);               while(top[x]!=top[y])               {                   if(deep[top[x]]<deep[top[y]])                      swap(x,y);                  addd(1,1,n,seg[top[x]],seg[x],z);                  x=fa[top[x]];              }              if(deep[x]>deep[y])swap(x,y);              addd(1,1,n,seg[x],seg[y],z);          }      }      re 0;  }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!