zoukankan      html  css  js  c++  java
  • bzoj2243 [SDOI2011]染色

    题目链接

    树上区间修改,用树链剖分+线段树

    只是这个题合并的时候不好有点坑,调了半天

    然后不知道为什么用现成的树剖求lca居然要T,改了倍增才过

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<string>
      7 #include<cmath>
      8 #include<ctime>
      9 #include<queue>
     10 #include<stack>
     11 #include<map>
     12 #include<set>
     13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
     14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
     15 #define Clear(a,b) memset(a,b,sizeof(a))
     16 #define inout(x) printf("%d",(x))
     17 #define douin(x) scanf("%lf",&x)
     18 #define strin(x) scanf("%s",(x))
     19 #define LLin(x) scanf("%lld",&x)
     20 #define op operator
     21 #define CSC main
     22 typedef unsigned long long ULL;
     23 typedef const int cint;
     24 typedef long long LL;
     25 using namespace std;
     26 void inin(int &ret)
     27 {
     28     ret=0;int f=0;char ch=getchar();
     29     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
     30     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
     31     ret=f?-ret:ret;
     32 }
     33 int n,m,shen[100010],head[100010],next[200020],zhi[200020],col[100010],ed,son[100010],fa[100010],dfn[100010],tot,top[100010];
     34 int ft[100010][18];
     35 void dfs1(int x)
     36 {
     37     son[x]=1;
     38     for(int i=1;i<=17;i++)
     39     {
     40         if(shen[x]<(1<<i))break;
     41         ft[x][i]=ft[ft[x][i-1]][i-1];
     42     }
     43     for(int i=head[x];i;i=next[i])if(zhi[i]!=ft[x][0])
     44     {
     45         shen[zhi[i]]=shen[x]+1;
     46         ft[zhi[i]][0]=x;
     47         dfs1(zhi[i]);
     48         son[x]+=son[zhi[i]];
     49     }
     50 }
     51 void dfs2(int x,int chain)
     52 {
     53     dfn[x]=++tot;top[x]=chain;
     54     int k=0;
     55     for(int i=head[x];i;i=next[i])
     56         if(shen[zhi[i]]>shen[x]&&son[k]<son[zhi[i]])
     57            k=zhi[i];
     58     if(!k)return;
     59     dfs2(k,chain);
     60     for(int i=head[x];i;i=next[i])
     61         if(shen[zhi[i]]>shen[x]&&k!=zhi[i])
     62            dfs2(zhi[i],zhi[i]);
     63 }
     64 void add(int a,int b)
     65 {
     66     next[++ed]=head[a],head[a]=ed,zhi[ed]=b;
     67     next[++ed]=head[b],head[b]=ed,zhi[ed]=a;
     68 }
     69 struct segtree
     70 {
     71     int sum,lc,rc,l,r,add;
     72     segtree(){lc=rc=sum=0;}
     73 }t[400040];
     74 void build(int k,int l,int r)
     75 {
     76     t[k].l=l;t[k].r=r;t[k].sum=1;t[k].add=0;
     77     if(l==r)return;
     78     int mid=(l+r)>>1;
     79     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
     80 }
     81 void update(int k,int a,int x)
     82 {
     83     int l=t[k].l,r=t[k].r,mid=(l+r)>>1,p1=k<<1,p2=p1|1;
     84     if(l==r)
     85     {
     86         t[k].sum=1,t[k].lc=t[k].rc=x;
     87         return ;
     88     }
     89     if(a<=mid)update(p1,a,x);
     90     else update(p2,a,x);
     91     t[k].sum=t[p1].sum+t[p2].sum;
     92     if(t[p1].rc==t[p2].lc)t[k].sum--;
     93     t[k].lc=t[p1].lc,t[k].rc=t[p2].rc;
     94 }
     95 void down(int k)
     96 {
     97     if(!t[k].add)return ;
     98     int p1=k<<1,p2=p1|1;
     99     t[p1].add=t[p2].add=t[k].add;
    100     t[p1].sum=t[p2].sum=1;
    101     t[p1].lc=t[p1].rc=t[p2].lc=t[p2].rc=t[k].add;
    102     t[k].add=0;
    103     if(t[p1].l==t[p1].r)col[t[p1].l]=t[p1].add;
    104     if(t[p2].l==t[p2].r)col[t[p2].l]=t[p2].add;
    105 }
    106 void change(int k,int x,int y,int c)
    107 {
    108     int l=t[k].l,r=t[k].r;
    109     if(l==x&&r==y)
    110     {t[k].lc=t[k].rc=c;t[k].sum=1;t[k].add=c;return;}
    111     down(k);
    112     int mid=(l+r)>>1;
    113     if(mid>=y)change(k<<1,x,y,c);
    114     else if(mid<x)change(k<<1|1,x,y,c);
    115     else
    116     {
    117         change(k<<1,x,mid,c);
    118         change(k<<1|1,mid+1,y,c);
    119     }
    120     t[k].lc=t[k<<1].lc;t[k].rc=t[k<<1|1].rc;
    121     if(t[k<<1].rc^t[k<<1|1].lc)t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
    122     else t[k].sum=t[k<<1].sum+t[k<<1|1].sum-1;
    123 }
    124 int query(int k,int x,int y)
    125 {
    126     int l=t[k].l,r=t[k].r;
    127     if(l==x&&r==y)return t[k].sum;
    128     down(k);
    129     int mid=(l+r)>>1;
    130     if(mid>=y)return query(k<<1,x,y);
    131     else if(mid<x)return query(k<<1|1,x,y);
    132     else
    133     {
    134         int tmp=1;
    135         if(t[k<<1].rc^t[k<<1|1].lc)tmp=0;
    136         return query(k<<1,x,mid)+query(k<<1|1,mid+1,y)-tmp;
    137     }
    138 }
    139 //int lca(int x,int y)
    140 //{
    141 //    while(top[x]!=top[y])
    142 //    {
    143 //        if(shen[top[x]]>shen[top[y]])x=fa[top[x]];
    144 //        else y=fa[top[y]];
    145 //    }
    146 //    return shen[x]>shen[y]?y:x;
    147 //}
    148 int lca(int x,int y)
    149 {
    150     if(shen[x]<shen[y])swap(x,y);
    151     int t=shen[x]-shen[y];
    152     for(int i=0;i<=17;i++)
    153        if(t&(1<<i))x=ft[x][i];
    154     for(int i=17;i>=0;i--)
    155        if(ft[x][i]!=ft[y][i])
    156        {x=ft[x][i];y=ft[y][i];}
    157     if(x==y)return x;
    158     return ft[x][0];
    159 }
    160 void change__(int x,int f,int c)
    161 {
    162     while(top[x]!=top[f])
    163     {
    164         change(1,dfn[top[x]],dfn[x],c);
    165         x=ft[top[x]][0]; 
    166     }
    167     change(1,dfn[f],dfn[x],c);
    168 }
    169 int getc(int k,int x)
    170 {
    171     int l=t[k].l,r=t[k].r;
    172     if(l==r)return t[k].lc;
    173     down(k);
    174     int mid=(l+r)>>1;
    175     if(x<=mid)return getc(k<<1,x);
    176     else return getc(k<<1|1,x);
    177 }
    178 int ad(int x,int f)
    179 {
    180     int ret=0;
    181     while(top[x]!=top[f])
    182     {
    183         ret+=query(1,dfn[top[x]],dfn[x]);
    184         if(getc(1,dfn[top[x]])==getc(1,dfn[ft[top[x]][0]]))ret--;
    185         x=ft[top[x]][0]; 
    186     }
    187     ret+=query(1,dfn[f],dfn[x]);
    188     return ret;
    189 }
    190 int CSC()
    191 {
    192     freopen("in.in","r",stdin);
    193     freopen("out.out","w",stdout);
    194     inin(n);inin(m);
    195     re(i,1,n)inin(col[i]);
    196     re(i,1,n-1)
    197     {
    198         int q,w;
    199         inin(q),inin(w);
    200         add(q,w);
    201     }
    202     dfs1(1);
    203     dfs2(1,1);
    204     build(1,1,n);
    205     for(int i=1;i<=n;i++)
    206         change(1,dfn[i],dfn[i],col[i]);
    207     re(i,1,m)
    208     {
    209         char opt[5];strin(opt);
    210         if(opt[0]=='C')
    211         {
    212             int q,w,e;
    213             inin(q),inin(w),inin(e);
    214             int r=lca(q,w);
    215             change__(q,r,e),change__(w,r,e);
    216         }
    217         if(opt[0]=='Q')
    218         {
    219             int q,w;
    220             inin(q),inin(w);
    221             int e=lca(q,w);
    222             printf("%d
    ",ad(q,e)+ad(w,e)-1);
    223         }
    224     }
    225     return 0;
    226 }
  • 相关阅读:
    HBuilder在线打包ipa步骤
    SWD烧录/仿真方式
    详解shell脚本括号区别--$()、$「 」、$「 」 、$(()) 、「 」 、「[ 」]
    Centos/Linux下调整分区大小(以home和根分区为例)
    Centos6.5安装中文支持和中文输入法
    如何用电路实现检测过零点?这个简单电路就能搞定
    ifconfig无输出的原因及解决办法
    Linux云服务器下Tomcat部署
    linux wget 命令用法详解(附实例说明)
    yum的repo文件详解、以及epel简介、yum源的更换
  • 原文地址:https://www.cnblogs.com/HugeGun/p/5151007.html
Copyright © 2011-2022 走看看