• bzoj2243 [SDOI2011]染色


      树链剖分,线段树维护三个值:区间颜色数、区间左端颜色、区间右端颜色,当左区间右端颜色=右区间左端颜色时候,总颜色-1,树上的维护类似。

      代码

      1 #include<cstdio>
      2 const int M = 1001010;
      3 const int N = 300010;
      4 int dp,p[N],pre[N],tt[N],size[N],f[N],gf[N],go[N],deep[N],color[N];
      5 int id[N],n,m,i,a,b,c,tot,e[N];
      6 int l[M],r[M],lc[M],rc[M],s[M],v[M]; 
      7 void link(int x,int y)
      8 {
      9     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
     10 }
     11 struct O{
     12     int ans,lc,rc;
     13     void clear()
     14     {
     15         ans=0;lc=0;rc=0;
     16     }
     17     void set(int a,int b,int c)
     18     {
     19         ans=a;lc=b;rc=c;
     20     }
     21 };
     22 void dfs(int x,int fa)
     23 {
     24     int i=p[x];
     25     size[x]=1;
     26     deep[x]=deep[fa]+1;
     27     while (i)
     28     {
     29         if (tt[i]!=fa)
     30         {
     31             f[tt[i]]=x;
     32             dfs(tt[i],x);
     33             if (size[tt[i]]>size[go[x]]) go[x]=tt[i];
     34             size[x]+=size[tt[i]]; 
     35         }
     36         i=pre[i];
     37     }
     38 }
     39 void gao(int x,int Fa,int fa)
     40 {
     41     int i=p[x];
     42     gf[x]=Fa;id[x]=++tot;e[tot]=color[x];
     43     if (go[x]) gao(go[x],Fa,x);
     44     while (i)
     45     {
     46         if ((tt[i]!=fa)&&(tt[i]!=go[x]))
     47             gao(tt[i],tt[i],x);
     48         i=pre[i];
     49     }
     50 }
     51 void updata(int x)
     52 {
     53     lc[x]=lc[2*x];
     54     rc[x]=rc[2*x+1];
     55     s[x]=s[2*x]+s[2*x+1];
     56     if (rc[2*x]==lc[2*x+1]) s[x]--;
     57 }
     58 void build(int x,int a,int b)
     59 {
     60     int m;
     61     l[x]=a;r[x]=b;v[x]=-1;
     62     if (b-a>1)
     63     {
     64         m=(a+b)>>1;
     65         build(2*x,a,m);
     66         build(2*x+1,m,b);
     67         updata(x);
     68     }
     69     else
     70     {
     71         lc[x]=e[b];
     72         rc[x]=e[b];
     73         s[x]=1;
     74     }
     75 }
     76 void clean(int x)
     77 {
     78     if (v[x]>=0)
     79     {
     80         s[x]=1;
     81         lc[x]=rc[x]=v[x];
     82         v[2*x]=v[x];
     83         v[2*x+1]=v[x];
     84         v[x]=-1;
     85     }
     86 }
     87 void change(int x,int a,int b,int c)
     88 {
     89     int m;
     90     clean(x);
     91     if ((a<=l[x])&&(r[x]<=b))
     92     {
     93         v[x]=c;
     94         return;
     95     }
     96     m=(l[x]+r[x])>>1;
     97     if (a<m) change(2*x,a,b,c);
     98     if (m<b) change(2*x+1,a,b,c);
     99     clean(2*x);clean(2*x+1);
    100     updata(x);
    101 }
    102 O query(int x,int a,int b)
    103 {
    104     int m;
    105     O tmp;tmp.clear();
    106     clean(x);
    107     if ((a<=l[x])&&(r[x]<=b))
    108     {
    109         tmp.set(s[x],lc[x],rc[x]);
    110         return tmp;
    111     }
    112     m=(l[x]+r[x])>>1;
    113     int L=-1,R=-1,A=-1;
    114     if (a<m) 
    115     {
    116         tmp=query(2*x,a,b);
    117         L=tmp.lc;
    118         R=tmp.rc;
    119         A=tmp.ans;    
    120     }
    121     if (m<b)
    122     {
    123         tmp=query(2*x+1,a,b);
    124         if (L==-1)
    125         {
    126             L=tmp.lc;
    127             R=tmp.rc;
    128             A=tmp.ans;    
    129         }
    130         else
    131         {
    132             A+=tmp.ans;
    133             if (R==tmp.lc) A--;
    134             R=tmp.rc;
    135         }
    136     }
    137     tmp.set(A,L,R);return tmp;
    138 }
    139 void gai(int a,int b,int c)
    140 {
    141     while (1)
    142     {
    143         if (gf[a]==gf[b])
    144         {
    145             if (deep[a]<deep[b]) a^=b^=a^=b;
    146             change(1,id[b]-1,id[a],c);
    147             return;
    148         }
    149         else
    150         {
    151             if (deep[gf[a]]<deep[gf[b]]) a^=b^=a^=b;
    152             change(1,id[gf[a]]-1,id[a],c);
    153             a=f[gf[a]];
    154         }
    155     }
    156 }
    157 int wen(int a,int b)
    158 {
    159     int ac=-1,bc=-1,ans=0;
    160     while (1)
    161     {
    162         if (gf[a]==gf[b])
    163         {
    164             if (deep[a]<deep[b]) a^=b^=a^=b,ac^=bc^=ac^=bc;
    165             O tmp=query(1,id[b]-1,id[a]);
    166             ans+=tmp.ans;
    167             if (tmp.rc==ac) ans--;
    168             if (tmp.lc==bc) ans--;
    169             return ans;
    170         }
    171         else
    172         {
    173             if (deep[gf[a]]<deep[gf[b]]) a^=b^=a^=b,ac^=bc^=ac^=bc;
    174             O tmp=query(1,id[gf[a]]-1,id[a]);
    175             ans+=tmp.ans;
    176             if (tmp.rc==ac) ans--;ac=tmp.lc;
    177             a=f[gf[a]];
    178         }
    179     }
    180 }
    181 int main()
    182 {
    183     scanf("%d%d",&n,&m);
    184     for (i=1;i<=n;i++)
    185         scanf("%d",&color[i]);
    186     for (i=1;i<n;i++)
    187     {
    188         scanf("%d%d",&a,&b);
    189         link(a,b);
    190         link(b,a);
    191     }
    192     dfs(1,0);
    193     gao(1,1,0);
    194     build(1,0,n);
    195     for (i=1;i<=m;i++)
    196     {
    197         char typ;
    198         scanf(" %c",&typ);
    199         if (typ=='Q')
    200         {
    201             scanf("%d%d",&a,&b);
    202             printf("%d
    ",wen(a,b));
    203         }
    204         else
    205         {
    206             scanf("%d%d%d",&a,&b,&c);
    207             gai(a,b,c);
    208         }
    209     }
    210 }
  • 相关阅读:
    下载并安装chrome插件的方法
    QString转化为char *的方式
    a socket demo
    TCP/IP相关知识总结(马士兵教育)视频对应图片
    C++中的按位或的用意
    dll路径加载顺序
    【第二周】【作业七】四人小组项目
    【第二周】【作业六】结对项目,四则运算++
    【第二周】【作业八】个人项目词频统计++
    【第二周】【作业三】效能测试
  • 原文地址:https://www.cnblogs.com/fzmh/p/5459459.html
Copyright © 2020-2023  润新知