• hdu_4897_Little Devil I(树链剖分)


    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4897

    题意:有三种操作,1是在树上的两个节点之间的路径改变当前的颜色,2是改变树上有且只有一个端点在u,v之间的边的颜色,3是询问u,v之间黑色边的条数

    题解:对于1,就是一般的树链剖分操作,对于2,我们知道树剖把树分成了重链和轻链,我们要充分利用这个结构才能降低时间复杂度,这里我们建立两个线段树来保存重链的sum和对每一个点的标记vis,第二个线段树表示如果这个点标记为1,那么以这个点周围的边都会改变,然后对于重链上的点,我们就直接在sum上操作,遇到轻链上的点,就在vis上标记,最后查询的时候先找sum上真实改变的边,然后当 当前的top跳到另一个top时,此时要查询vis上和sum上异或的值,最后全部加起来就是答案,要好好的想一想才能理解

      1 #include<cstdio>
      2 #define F(i,a,b) for(int i=a;i<=b;i++)
      3 
      4 const int N=1e5+7;
      5 int t,n,op,q,x,y,g[N],nxt[N<<1],v[N<<1],ed;
      6 inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
      7 //--------------树链剖分---------------
      8 int dep[N],sz[N],hs[N],top[N],fa[N],tid[N],idx;
      9 void dfs1(int u,int pre){
     10     fa[u]=pre,sz[u]=1,dep[u]=dep[pre]+1,hs[u]=0;
     11     for(int i=g[u];~i;i=nxt[i])if(v[i]!=pre)
     12     dfs1(v[i],u),sz[u]+=sz[v[i]],hs[u]=sz[v[i]]>sz[hs[u]]?v[i]:hs[u];
     13 }
     14 void dfs2(int u,int tp){
     15     tid[u]=++idx,top[u]=tp;
     16     if(hs[u])dfs2(hs[u],tp);
     17     for(int i=g[u];~i;i=nxt[i])
     18     if(v[i]!=fa[u]&&v[i]!=hs[u])dfs2(v[i],v[i]);
     19 }
     20 //--------------线段树------------------
     21 #define root 1,n,1
     22 #define ls l,m,rt<<1
     23 #define rs m+1,r,rt<<1|1
     24 int sum[N<<2],vis[N<<2],ly1[N<<2];
     25 
     26 inline void sink(int rt,int tot){ly1[rt]^=1,sum[rt]=tot-sum[rt];}
     27 
     28 inline void pd(int op,int l,int r,int rt){
     29     if(op==1){
     30         if(ly1[rt]){
     31         int m=(l+r)>>1;
     32         sink(rt<<1,m-l+1),sink(rt<<1|1,r-m);
     33         ly1[rt]=0;
     34         }
     35     }else if(vis[rt])vis[rt<<1]^=1,vis[rt<<1|1]^=1,vis[rt]=0;
     36 }
     37 inline void up_p(int L,int R,int l,int r,int rt){
     38     if(L<=l&&r<=R){
     39         sink(rt,r+1-l);
     40         return;
     41     }
     42     pd(1,l,r,rt);
     43     int m=(l+r)>>1;
     44     if(L<=m)up_p(L,R,ls);
     45     if(R>m)up_p(L,R,rs);
     46     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
     47 }
     48 inline int q_p(int L,int R,int l,int r,int rt){
     49     if(L<=l&&r<=R)return sum[rt];
     50     int m=(l+r)>>1,ret=0;
     51     pd(1,l,r,rt);
     52     if(L<=m)ret+=q_p(L,R,ls);
     53     if(m<R)ret+=q_p(L,R,rs);
     54     return ret;
     55 }
     56 inline void up_v(int L,int R,int l,int r,int rt){
     57     if(L<=l&&r<=R){vis[rt]^=1;return;}
     58     pd(2,l,r,rt);
     59     int m=(l+r)>>1;
     60     if(L<=m)up_v(L,R,ls);
     61     if(R>m)up_v(L,R,rs);
     62 }
     63 inline int q_v(int x,int l,int r,int rt){
     64     if(l==r)return vis[rt];
     65     pd(2,l,r,rt);
     66     int m=(l+r)>>1,ret=0;
     67     if(x<=m)ret^=q_v(x,ls);
     68     else ret^=q_v(x,rs);
     69     return ret;
     70 }
     71 //--------------------------------------
     72 inline int ask(int x,int y){
     73     int ans=0;
     74     while(top[x]!=top[y]){
     75         if(dep[top[x]]<dep[top[y]])x^=y,y^=x,x^=y;
     76         if(x!=top[x])ans+=q_p(tid[top[x]]+1,tid[x],root);
     77         ans+=q_v(tid[fa[top[x]]],root)^q_p(tid[top[x]],tid[top[x]],root);
     78         x=fa[top[x]];
     79     }    
     80     if(x==y)return ans;
     81     if(dep[x]>dep[y])x^=y,y^=x,x^=y;
     82     ans+=q_p(tid[x]+1,tid[y],root);
     83     return ans;
     84 }
     85 inline void up(int op,int x,int y){
     86     if(op==1){
     87         while(top[x]!=top[y]){
     88             if(dep[top[x]]<dep[top[y]])x^=y,y^=x,x^=y;
     89             up_p(tid[top[x]],tid[x],root),x=fa[top[x]];
     90         }
     91         if(x!=y){
     92             if(dep[x]>dep[y])x^=y,y^=x,x^=y;
     93             up_p(tid[x]+1,tid[y],root);
     94         }
     95     }else{
     96         while(top[x]!=top[y]){
     97             if(dep[top[x]]<dep[top[y]])x^=y,y^=x,x^=y;
     98             up_v(tid[top[x]],tid[x],root);
     99             up_p(tid[top[x]],tid[top[x]],root);
    100             if(hs[x])up_p(tid[x]+1,tid[hs[x]],root);
    101             x=fa[top[x]];
    102         }
    103             if(dep[x]>dep[y])x^=y,y^=x,x^=y;
    104             up_v(tid[x],tid[y],root);
    105             up_p(tid[x],tid[x],root);
    106             if(hs[y])up_p(tid[y]+1,tid[hs[y]],root);
    107     }
    108 }
    109 
    110 int main(){
    111     scanf("%d",&t);
    112     while(t--){
    113         scanf("%d",&n);
    114         F(i,0,n)g[i]=-1;ed=0;
    115         F(i,0,n<<2)sum[i]=0,vis[i]=0,ly1[i]=0;
    116         F(i,1,n-1)scanf("%d%d",&x,&y),adg(x,y),adg(y,x);
    117         dfs1(1,0),idx=0,dfs2(1,1),scanf("%d",&q);
    118         while(q--){
    119             scanf("%d%d%d",&op,&x,&y);
    120             if(op<3)up(op,x,y);else printf("%d
    ",ask(x,y));    
    121         }
    122     }
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    HTML的基本知识
    java script后续
    java script
    CSS
    DAY 33 进程理论与进程方法
    DAY 32 UDP协议、Socketserver模块,并发编程基础
    DAY 30 网络编程基础
    DAY 25多态、反射、异常处理
    DAY 24继承与组合
    DAY 23 面向对象(二)
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5696105.html
Copyright © 2020-2023  润新知