zoukankan      html  css  js  c++  java
  • Cogs 1583. [POJ3237]树的维护 LCT,树链剖分

    题目:http://cojs.tk/cogs/problem/problem.php?pid=1583

    1583. [POJ3237]树的维护

    ★★★☆   输入文件:maintaintree.in   输出文件:maintaintree.out   简单对比
    时间限制:5 s   内存限制:128 MB

    【题目描述】

    给你由N个结点组成的树。树的节点被编号为1到N,边被编号为1到N-1。每一条边有一个权值。然后你要在树上执行一系列指令。指令可以是如下三种之一:

    CHANGE i v:将第i条边的权值改成v。

    NEGATE a b:将点a到点b路径上所有边的权值变成其相反数。

    QUERY a b:找出点a到点b路径上各边的最大权值。

    【输入格式】

    输入文件的第一行有一个整数N(N<=10000)。

    接下来N-1行每行有三个整数a,b,c,代表点a和点b之间有一条权值为c的边。这些边按照其编号从小到大给出。

    接下来是若干条指令(不超过10^5条),都按照上面所说的格式。

    输入文件的最后一行是"DONE".

    【输出格式】

    对每个“QUERY”指令,输出一行,即路径上各边的最大权值。

    【样例输入】

    3

    1 2 1

    2 3 2

    QUERY 1 2

    CHANGE 1 3

    QUERY 1 2

    DONE

    【样例输出】

    1

    3

    【提示】

    这里的输入输出格式和POJ上原题略有不同。

    【来源】

    POJ 3237 Tree

    题解:

    LCT维护一下最大值和最小值,当要变为相反数时,把 最大值变为原来的最小值的相反数,最小值变为原来最大值的相反数 即可。。。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define INF 1e9
      4 #define MAXN 10010
      5 struct node
      6 {
      7     int left,right,mx,mn,val;
      8 }tree[2*MAXN];
      9 int rev[2*MAXN],tag[2*MAXN],father[2*MAXN],Stack[2*MAXN],n;
     10 int read()
     11 {
     12     int s=0,fh=1;char ch=getchar();
     13     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
     14     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
     15     return s*fh;
     16 }
     17 int isroot(int x)
     18 {
     19     return tree[father[x]].left!=x&&tree[father[x]].right!=x;
     20 }
     21 void pushdown(int x)
     22 {
     23     int l=tree[x].left,r=tree[x].right;
     24     if(rev[x]!=0)
     25     {
     26         rev[x]^=1;rev[l]^=1;rev[r]^=1;
     27         swap(tree[x].left,tree[x].right);
     28     }
     29     if(tag[x]!=0)
     30     {
     31         tag[x]^=1;tag[l]^=1;tag[r]^=1;
     32         tree[l].val=-tree[l].val;
     33         tree[r].val=-tree[r].val;
     34         swap(tree[l].mx,tree[l].mn);
     35         tree[l].mx=-tree[l].mx;tree[l].mn=-tree[l].mn;
     36         swap(tree[r].mx,tree[r].mn);
     37         tree[r].mx=-tree[r].mx;tree[r].mn=-tree[r].mn;
     38     }
     39 }
     40 void pushup(int x)
     41 {
     42     int l=tree[x].left,r=tree[x].right;
     43     tree[x].mx=max(tree[l].mx,tree[r].mx);
     44     if(x>n)tree[x].mx=max(tree[x].mx,tree[x].val);
     45     tree[x].mn=min(tree[l].mn,tree[r].mn);
     46     if(x>n)tree[x].mn=min(tree[x].mn,tree[x].val);
     47 }
     48 void rotate(int x)
     49 {
     50     int y=father[x],z=father[y];
     51     if(!isroot(y))
     52     {
     53         if(tree[z].left==y)tree[z].left=x;
     54         else tree[z].right=x;
     55     }
     56     if(tree[y].left==x)
     57     {
     58         father[x]=z;father[y]=x;tree[y].left=tree[x].right;tree[x].right=y;father[tree[y].left]=y;
     59     }
     60     else
     61     {
     62         father[x]=z;father[y]=x;tree[y].right=tree[x].left;tree[x].left=y;father[tree[y].right]=y;
     63     }
     64     pushup(y);pushup(x);
     65 }
     66 void splay(int x)
     67 {
     68     int top=0,i,y,z;Stack[++top]=x;
     69     for(i=x;!isroot(i);i=father[i])Stack[++top]=father[i];
     70     for(i=top;i>=1;i--)pushdown(Stack[i]);
     71     while(!isroot(x))
     72     {
     73         y=father[x],z=father[y];
     74         if(!isroot(y))
     75         {
     76             if((tree[y].left==x)^(tree[z].left==y))rotate(x);
     77             else rotate(y);
     78         }
     79         rotate(x);
     80     }
     81 }
     82 void access(int x)
     83 {
     84     int last=0;
     85     while(x!=0)
     86     {
     87         splay(x);
     88         tree[x].right=last;pushup(x);
     89         last=x;x=father[x];
     90     }
     91 }
     92 void makeroot(int x)
     93 {
     94     access(x);splay(x);rev[x]^=1;
     95 }
     96 void link(int u,int v)
     97 {
     98     makeroot(u);father[u]=v;splay(u);
     99 }
    100 void cut(int u,int v)
    101 {
    102     makeroot(u);access(v);splay(v);father[u]=tree[v].left=0;
    103 }
    104 int findroot(int x)
    105 {
    106     access(x);splay(x);
    107     while(tree[x].left!=0)x=tree[x].left;
    108     return x;
    109 }
    110 int main()
    111 {
    112     freopen("maintaintree.in","r",stdin);
    113     freopen("maintaintree.out","w",stdout);
    114     int i,a,b,c;
    115     char fh[8];
    116     n=read();
    117     for(i=0;i<=2*n;i++)tree[i].mx=-INF,tree[i].mn=INF;
    118     for(i=1;i<n;i++)
    119     {
    120         a=read();b=read();c=read();
    121         tree[n+i].mx=tree[n+i].mn=tree[n+i].val=c;
    122         link(a,n+i);link(n+i,b);
    123     }
    124     while(1)
    125     {
    126         scanf("
    %s",fh);
    127         if(fh[0]=='D')break;
    128         if(fh[0]=='Q')
    129         {
    130             a=read();b=read();
    131             makeroot(a);access(b);splay(b);
    132             printf("%d
    ",tree[b].mx);
    133         }
    134         else if(fh[0]=='C')
    135         {
    136             a=read();b=read();
    137             makeroot(n+a);tree[n+a].mn=tree[n+a].mx=tree[n+a].val=b;
    138         }
    139         else
    140         {
    141             a=read();b=read();
    142             makeroot(a);access(b);splay(b);
    143             tag[b]^=1;
    144             swap(tree[b].mx,tree[b].mn);
    145             tree[b].val=-tree[b].val;
    146             tree[b].mx=-tree[b].mx;
    147             tree[b].mn=-tree[b].mn;
    148         }
    149     }
    150     fclose(stdin);
    151     fclose(stdout);
    152     return 0;
    153 }
    View Code

     2016.3.24

    补一发树链剖分:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define MAXN 10010
      4 #define INF 1e9
      5 struct node
      6 {
      7     int begin,end,value,next;
      8 }edge[2*MAXN];
      9 struct NODE
     10 {
     11     int left,right,mx,mn,tag;
     12 }tree[5*MAXN];
     13 int cnt,Head[MAXN],n,size[MAXN],deep[MAXN],P[MAXN][14],pos[MAXN],belong[MAXN],id[MAXN],vv[MAXN],U[MAXN],V[MAXN],VAL[MAXN],SIZE;
     14 bool vis[MAXN];
     15 void addedge(int bb,int ee,int vv)
     16 {
     17     edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
     18 }
     19 void addedge1(int bb,int ee,int vv)
     20 {
     21     addedge(bb,ee,vv);addedge(ee,bb,vv);
     22 }
     23 int read()
     24 {
     25     int s=0,fh=1;char ch=getchar();
     26     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
     27     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
     28     return s*fh;
     29 }
     30 void dfs1(int u)
     31 {
     32     int i,v;
     33     size[u]=1;vis[u]=true;
     34     for(i=Head[u];i!=-1;i=edge[i].next)
     35     {
     36         v=edge[i].end;
     37         if(vis[v]==false)
     38         {
     39             deep[v]=deep[u]+1;
     40             P[v][0]=u;
     41             dfs1(v);
     42             size[u]+=size[v];
     43         }
     44     }
     45 }
     46 void Ycl()
     47 {
     48     int i,j;
     49     for(j=1;(1<<j)<=n;j++)
     50     {
     51         for(i=1;i<=n;i++)
     52         {
     53             if(P[i][j-1]!=-1)P[i][j]=P[P[i][j-1]][j-1];
     54         }
     55     }
     56 }
     57 void dfs2(int u,int chain)
     58 {
     59     int k=0,i,v;
     60     pos[u]=++SIZE;belong[u]=chain;
     61     for(i=Head[u];i!=-1;i=edge[i].next)
     62     {
     63         v=edge[i].end;
     64         if(deep[v]>deep[u]&&size[v]>size[k])k=v;
     65     }
     66     if(k==0)return;
     67     dfs2(k,chain);
     68     for(i=Head[u];i!=-1;i=edge[i].next)
     69     {
     70         v=edge[i].end;
     71         if(deep[v]>deep[u]&&v!=k)dfs2(v,v);
     72     }
     73 }
     74 int LCA(int x,int y)
     75 {
     76     int i,j;
     77     if(deep[x]<deep[y])swap(x,y);
     78     for(i=0;(1<<i)<=deep[x];i++);i--;
     79     for(j=i;j>=0;j--)if(deep[x]-(1<<j)>=deep[y])x=P[x][j];
     80     if(x==y)return x;
     81     for(j=i;j>=0;j--)
     82     {
     83         if(P[x][j]!=-1&&P[x][j]!=P[y][j])
     84         {
     85             x=P[x][j];
     86             y=P[y][j];
     87         }
     88     }
     89     return P[x][0];
     90 }
     91 void Pushup(int k)
     92 {
     93     tree[k].mx=max(tree[k*2].mx,tree[k*2+1].mx);
     94     tree[k].mn=min(tree[k*2].mn,tree[k*2+1].mn);
     95 }
     96 void Pushdown(int k)
     97 {
     98     int l=k*2,r=k*2+1;
     99     if(tree[k].tag!=0)
    100     {
    101         tree[k].tag^=1;tree[l].tag^=1;tree[r].tag^=1;
    102         swap(tree[l].mn,tree[l].mx);
    103         tree[l].mn=-tree[l].mn;tree[l].mx=-tree[l].mx;
    104         swap(tree[r].mn,tree[r].mx);
    105         tree[r].mn=-tree[r].mn;tree[r].mx=-tree[r].mx;
    106     }
    107 }
    108 void Build(int k,int l,int r)
    109 {
    110     tree[k].left=l;tree[k].right=r;tree[k].mx=-INF;tree[k].mn=INF;tree[k].tag=0;
    111     if(l==r)
    112     {
    113         tree[k].mx=tree[k].mn=vv[l];
    114         return;
    115     }
    116     int mid=(l+r)/2;
    117     Build(k*2,l,mid);Build(k*2+1,mid+1,r);
    118     Pushup(k);
    119 }
    120 void Change(int k,int lr,int C)
    121 {
    122     if(tree[k].left==tree[k].right){tree[k].mx=tree[k].mn=C;return;}
    123     Pushdown(k);
    124     int mid=(tree[k].left+tree[k].right)/2;
    125     if(lr<=mid)Change(k*2,lr,C);
    126     else Change(k*2+1,lr,C);
    127     Pushup(k);
    128 }
    129 int Query_max(int k,int l,int r)
    130 {
    131     if(l<=tree[k].left&&tree[k].right<=r)return tree[k].mx;
    132     Pushdown(k);
    133     int mid=(tree[k].left+tree[k].right)/2;
    134     if(r<=mid)return Query_max(k*2,l,r);
    135     else if(l>mid)return Query_max(k*2+1,l,r);
    136     else return max(Query_max(k*2,l,mid),Query_max(k*2+1,mid+1,r));
    137 }
    138 int Solve_max(int x,int f)
    139 {
    140     int MAX=-INF;
    141     while(belong[x]!=belong[f])
    142     {
    143         MAX=max(MAX,Query_max(1,pos[belong[x]],pos[x]));
    144         x=P[belong[x]][0];
    145     }
    146     if(x!=f)MAX=max(MAX,Query_max(1,pos[f]+1,pos[x]));
    147     return MAX;
    148 }
    149 void Negate(int k,int l,int r)
    150 {
    151     if(l<=tree[k].left&&tree[k].right<=r/*tree[k].left==tree[k].right*/)
    152     {
    153         swap(tree[k].mn,tree[k].mx);
    154         tree[k].mn=-tree[k].mn;tree[k].mx=-tree[k].mx;
    155         tree[k].tag^=1;
    156         return;
    157     }
    158     Pushdown(k);
    159     int mid=(tree[k].left+tree[k].right)/2;
    160     if(r<=mid)Negate(k*2,l,r);
    161     else if(l>mid)Negate(k*2+1,l,r);
    162     else {Negate(k*2,l,mid);Negate(k*2+1,mid+1,r);}
    163     Pushup(k);
    164 }
    165 void Solve_negate(int x,int f)
    166 {
    167     while(belong[x]!=belong[f])
    168     {
    169         Negate(1,pos[belong[x]],pos[x]);
    170         x=P[belong[x]][0];
    171     }
    172     if(x!=f)Negate(1,pos[f]+1,pos[x]);
    173 }
    174 int main()
    175 {
    176     freopen("maintaintree.in","r",stdin);
    177     freopen("maintaintree.out","w",stdout);
    178     int i,I,W,bb,ee,lca;
    179     char fh[8];
    180     n=read();
    181     memset(Head,-1,sizeof(Head));cnt=1;
    182     for(i=1;i<n;i++)
    183     {
    184         U[i]=read();V[i]=read();VAL[i]=read();
    185         addedge1(U[i],V[i],VAL[i]);
    186     }
    187     memset(P,-1,sizeof(P));SIZE=0;
    188     dfs1(1);Ycl();
    189     dfs2(1,1);
    190     for(i=1;i<n;i++)
    191     {
    192         if(deep[U[i]]>deep[V[i]])id[i]=U[i];
    193         else id[i]=V[i];
    194     }
    195     for(i=1;i<n;i++)vv[pos[id[i]]]=VAL[i];
    196     Build(1,1,n);
    197     while(1)
    198     {
    199         scanf("
    %s",fh);
    200         if(fh[0]=='D')break;
    201         if(fh[0]=='C')
    202         {
    203             I=read();W=read();
    204             Change(1,pos[id[I]],W);
    205         }
    206         else if(fh[0]=='Q')
    207         {
    208             bb=read();ee=read();
    209             lca=LCA(bb,ee);
    210             printf("%d
    ",max(Solve_max(bb,lca),Solve_max(ee,lca)));
    211         }
    212         else
    213         {
    214             bb=read();ee=read();
    215             lca=LCA(bb,ee);
    216             Solve_negate(bb,lca);
    217             Solve_negate(ee,lca);
    218         }
    219     }
    220     fclose(stdin);
    221     fclose(stdout);
    222     return 0;
    223 }
  • 相关阅读:
    Xn数列(codevs 1281)
    素数密度(洛谷 1835)
    Sightseeing(poj 3463)
    线段树——Ultra-QuickSort
    最大子矩阵
    完成作业的先后顺序
    堆积木块的最大高度
    最长上升序列和
    最长上升子序列
    高精度乘法程序
  • 原文地址:https://www.cnblogs.com/Var123/p/5278965.html
Copyright © 2011-2022 走看看