• bzoj2243[SDOI2011]染色


    bzoj2243[SDOI2011]染色

    题意:

    n点无根树,2类操作:将节点a到节点b路径上所有点都染成颜色c、询问节点a到节点b路径上的颜色段数量。

    题解:

    有点恶心的链剖,可以用包含区间颜色段数,左端点颜色,右端点颜色的结构体存储查询的结果。首先是线段树节点除了要保存区间颜色段数还要保存左右端点颜色,再者是查询的时候要注意合并区间:在线段树查询时,如果递归左端点,就左合并递归结果,如果右端点就右合并;在树链查询时,从下往上左合并查询结果,两段分开处理,当两段都查询完时将一段的结果中的左右端点颜色交换,然后合并。

    代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #define inc(i,j,k) for(int i=j;i<=k;i++)
      5 #define maxn 200000
      6 using namespace std;
      7 
      8 struct e{int t,n;}; e es[maxn];int ess,g[maxn];
      9 void pe(int f,int t){es[++ess]=(e){t,g[f]}; g[f]=ess; es[++ess]=(e){f,g[t]}; g[t]=ess;}
     10 int fa[maxn],sz[maxn],dep[maxn],pos[maxn],top[maxn],v[maxn][2],sgs;
     11 int l[maxn*4],r[maxn*4],ch[maxn*4][2],ll[maxn*4],rr[maxn*4],sm[maxn*4],tg[maxn*4];
     12 struct nd{
     13     int sm,l,r;
     14     void plusr(nd d){
     15         sm=sm+d.sm+(r==d.l?-1:0); r=d.r;
     16     }
     17     void plusl(nd d){
     18         sm=sm+d.sm+(d.r==l?-1:0); l=d.l;
     19     }
     20 };
     21 void dfs(int x){
     22     sz[x]=1; for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa[x]){
     23         dep[es[i].t]=dep[x]+1; fa[es[i].t]=x; dfs(es[i].t); sz[x]+=sz[es[i].t];
     24     }
     25 }
     26 void buildchain(int x,int ps){
     27     pos[x]=++sgs; top[x]=ps; v[sgs][1]=v[x][0]; int mx1,mx2=0;
     28     for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa[x]&&mx2<sz[es[i].t])mx2=sz[es[i].t],mx1=es[i].t;
     29     if(mx2)buildchain(mx1,ps);
     30     for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa[x]&&es[i].t!=mx1)buildchain(es[i].t,es[i].t);
     31 }
     32 int lca(int x,int y){
     33     for(;top[x]!=top[y];x=fa[top[x]])if(dep[top[x]]<dep[top[y]])swap(x,y);
     34     return dep[x]<dep[y]?x:y;
     35 }
     36 void update(int x){
     37     if(!x)return; if(!ch[x][0]&&!ch[x][1])sm[x]=0;
     38     sm[x]=sm[ch[x][0]]+sm[ch[x][1]]+(rr[ch[x][0]]==ll[ch[x][1]]?-1:0);
     39     ll[x]=ll[ch[x][0]]; rr[x]=rr[ch[x][1]];
     40 }
     41 void pushdown(int x){
     42     if(!x||tg[x]==-1)return; int lc=ch[x][0],rc=ch[x][1];
     43     if(lc)sm[lc]=1,ll[lc]=rr[lc]=tg[x],tg[lc]=tg[x];
     44     if(rc)sm[rc]=1,ll[rc]=rr[rc]=tg[x],tg[rc]=tg[x]; tg[x]=-1;
     45 }
     46 void build(int x,int L,int R){
     47     if(L==R)l[x]=r[x]=L,ch[x][0]=ch[x][1]=0,ll[x]=rr[x]=v[L][1],tg[x]=-1,sm[x]=1;else{
     48         int M=(L+R)>>1; ch[x][0]=x<<1; ch[x][1]=x<<1|1; l[x]=L; r[x]=R; tg[x]=-1;
     49         build(ch[x][0],L,M); build(ch[x][1],M+1,R); update(x);
     50     }
     51 }
     52 nd query(int x,int L,int R){
     53     pushdown(x); if(L<=l[x]&&r[x]<=R)return (nd){sm[x],ll[x],rr[x]};
     54     int M=(l[x]+r[x])>>1; nd q;
     55     if(L<=M){
     56         q=query(ch[x][0],L,R); if(M<R)q.plusr(query(ch[x][1],L,R));
     57     }else if(M<R)q=(query(ch[x][1],L,R));
     58     return q;
     59 }
     60 void change(int x,int L,int R,int col){
     61     pushdown(x); if(L<=l[x]&&r[x]<=R){ll[x]=rr[x]=tg[x]=col,sm[x]=1; return;}
     62     int M=(l[x]+r[x])>>1; if(L<=M)change(ch[x][0],L,R,col);
     63     if(M<R)change(ch[x][1],L,R,col); update(x);
     64 }
     65 void init1(){ess=0; memset(g,0,sizeof(g));}
     66 void init2(){fa[1]=0; dep[1]=0; dfs(1); sgs=0; buildchain(1,1); build(1,1,sgs);}
     67 int querysum(int a,int b){
     68     if(a==b)return query(1,pos[a],pos[b]).sm; int c=lca(a,b);
     69     nd q1; bool f=0;
     70     while(dep[top[a]]>dep[top[c]]){
     71         if(!f)q1=query(1,pos[top[a]],pos[a]),f=1;else q1.plusl(query(1,pos[top[a]],pos[a]));
     72         a=fa[top[a]];
     73     }
     74     if(!f)q1=query(1,pos[c],pos[a]),f=1;else q1.plusl(query(1,pos[c],pos[a]));
     75     nd q2; f=0;
     76     while(dep[top[b]]>dep[top[c]]){
     77         if(! f)q2=query(1,pos[top[b]],pos[b]),f=1;else q2.plusl(query(1,pos[top[b]],pos[b]));
     78         b=fa[top[b]];
     79     }
     80     if(! f)q2=query(1,pos[c],pos[b]),f=1;else q2.plusl(query(1,pos[c],pos[b]));
     81     swap(q1.l,q1.r); q1.plusr(q2); return q1.sm;
     82 }
     83 void changecol(int a,int b,int col){
     84     if(a==b){change(1,pos[a],pos[b],col);} int c=lca(a,b);
     85     while(dep[top[a]]>dep[top[c]])change(1,pos[top[a]],pos[a],col),a=fa[top[a]];
     86     change(1,pos[c],pos[a],col);
     87     while(dep[top[b]]>dep[top[c]])change(1,pos[top[b]],pos[b],col),b=fa[top[b]];
     88     change(1,pos[c],pos[b],col);
     89 }
     90 int n,m; char op[3];
     91 int main(){
     92     //freopen("test.txt","r",stdin);
     93     scanf("%d%d",&n,&m); inc(i,1,n)scanf("%d",&v[i][0]); init1();
     94     inc(i,1,n-1){int a,b; scanf("%d%d",&a,&b); pe(a,b);} init2();
     95     inc(i,1,m){
     96         int a,b,c; scanf("%s%d%d",op,&a,&b);
     97         if(op[0]=='Q'){printf("%d
    ",querysum(a,b));}
     98         if(op[0]=='C'){scanf("%d",&c); changecol(a,b,c);}
     99     }
    100     return 0;
    101 }

    20160427

  • 相关阅读:
    2020 春 学期总结
    计算机科学的咬文嚼字:“并行”与“并发”
    Codeforces 1251E Voting
    Codeforces 1251D Salary Changing
    Asia Jakarta Regional Contest 2019 I
    hdu1007 Quoit Design
    2019春季学期回忆和总结
    bzoj5017 [Snoi2017]炸弹
    我永远讨厌gch文件
    bzoj5102 [POI2018]Prawnicy
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5689611.html
Copyright © 2020-2023  润新知