• 1036: [ZJOI2008]树的统计Count


    链剖

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 #define INF 1000000000
     7 #define N 30000*4
     8 int n,m,cnt,num[N],fa[N],sum[N],mmax[N],size[N],depth[N],at[N],son[N],head[N];
     9 int tot,g[N],nnext[N],v[N];
    10 void Add(int x,int y){tot++;nnext[tot]=g[x];g[x]=tot;v[tot]=y;}
    11 void Dfs(int x)
    12 {
    13     int max_size=0;size[x]=1;
    14     for(int i=g[x];i;i=nnext[i])
    15     {
    16         int tmp=v[i];
    17         if(tmp!=fa[x])
    18         {
    19             fa[tmp]=x;
    20             depth[tmp]=depth[x]+1;
    21             Dfs(tmp);
    22             size[x]+=size[tmp];
    23             if(size[tmp]>size[max_size]) max_size=tmp;
    24         }
    25     }
    26     son[x]=max_size;
    27 }
    28 void Build(int x,int top)
    29 {
    30     at[x]=++cnt;
    31     head[x]=top;
    32     if(son[x]!=0) Build(son[x],top);
    33     for(int i=g[x];i;i=nnext[i])
    34     {
    35         int tmp=v[i];
    36         if(tmp!=fa[x]&&tmp!=son[x])
    37         {
    38             Build(tmp,tmp);
    39         }
    40     }
    41 }
    42 void Up(int x)
    43 {
    44     sum[x]=sum[x*2]+sum[x*2+1];
    45     mmax[x]=max(mmax[x*2+1],mmax[x*2]);
    46 }
    47 void Change(int now,int L,int R,int loc,int x)
    48 {
    49     if(L==R) {num[L]=x;sum[now]=x;mmax[now]=x;return ;}
    50     int mid=(L+R)/2;
    51     if(loc<=mid) Change(now*2,L,mid,loc,x);
    52     else Change(now*2+1,mid+1,R,loc,x);
    53     Up(now);
    54 }
    55 int ans_mmax=-INF,ans_sum=0;
    56 void F(int now,int L,int R,int s,int t)
    57 {
    58     if(s<=L&&t>=R)
    59     {
    60         ans_mmax=max(ans_mmax,mmax[now]);
    61         ans_sum+=sum[now];return ;
    62     }
    63     int mid=(L+R)/2;
    64     if(s<=mid) F(now*2,L,mid,s,t);
    65     if(mid+1<=t) F(now*2+1,mid+1,R,s,t);
    66 }
    67 void Lca(int x,int y)
    68 {
    69     while(head[x]!=head[y])
    70     {
    71         if(depth[head[x]]<depth[head[y]]) swap(x,y);
    72         F(1,1,n,at[head[x]],at[x]);
    73         x=fa[head[x]];    
    74     }
    75     if(!x)return ;
    76     if(depth[x]<depth[y]) swap(x,y);
    77     F(1,1,n,at[y],at[x]);
    78 }
    79 int main()
    80 {
    81     cin>>n;int x,y;
    82     for(int i=1;i<n;i++) scanf("%d %d",&x,&y),Add(x,y),Add(y,x);
    83     Dfs(1);Build(1,1);
    84     for(int i=1;i<=n;i++) scanf("%d",&x),Change(1,1,n,at[i],x); 
    85     char s[100];
    86     cin>>m;
    87     while(m--)
    88     {
    89         scanf("%s %d %d",s+1,&x,&y);
    90         switch(s[2])
    91         {
    92             case 'M':ans_mmax=-INF;Lca(x,y);printf("%d
    ",ans_mmax);break;
    93             case 'H':Change(1,1,n,at[x],y);break;
    94             case 'S':ans_sum=0;Lca(x,y);printf("%d
    ",ans_sum);break;
    95         }
    96     }
    97     return 0;
    98 }
    链剖

    LCT  to[N][0] 233333

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 using namespace std;
     6 #define N 30000+10
     7 #define INF 1000000000
     8 #define L(x) to[x][0]
     9 #define R(x) to[x][1]
    10 int n,m,fa[N],to[N][2],num[N],mmax[N],sum[N];
    11 bool mark[N];
    12 void Up(int x)
    13 {
    14   sum[x]=sum[L(x)]+sum[R(x)]+num[x];
    15   mmax[x]=max(num[x],max(mmax[L(x)],mmax[R(x)]));
    16 }
    17 void Pushdown(int x)
    18 {
    19   if(!mark[x])return ;
    20   mark[x]=false;
    21   swap(L(x),R(x));
    22   mark[L(x)]^=1;
    23   mark[R(x)]^=1;
    24 }
    25 bool Is(int x)
    26 {
    27   return L(fa[x])!=x&&R(fa[x])!=x;
    28 }bool ok=false;
    29 void Rotate(int x)
    30 {
    31   int y=fa[x],z=fa[y];    
    32   Pushdown(y);Pushdown(x);
    33   if(!Is(y)) to[z][to[z][1]==y]=x;
    34   int c=to[y][1]==x;
    35   fa[x]=z;fa[y]=x;fa[to[x][c^1]]=y;
    36   to[y][c]=to[x][c^1];to[x][c^1]=y;
    37   Up(y);Up(x);
    38 }
    39 void Splay(int x)
    40 {
    41 
    42   Pushdown(x);
    43   while(!Is(x))
    44   {
    45     if(!Is(fa[x])) Rotate(fa[x]);
    46     Rotate(x);
    47   }
    48 }
    49 void Access(int x)
    50 {
    51   int t=0;
    52   while(x)
    53   {
    54     Splay(x);
    55     R(x)=t;
    56     t=x;Up(x);
    57     
    58     x=fa[x];
    59   }
    60 }
    61 void Markroot(int x)
    62 {
    63   Access(x);Splay(x);mark[x]^=1;
    64 }
    65 void Change(int x,int y)
    66 {
    67   Splay(x);num[x]=y;Up(x);
    68 }
    69 void Link(int x,int y)
    70 {
    71     Markroot(x);fa[x]=y;
    72 }
    73 int F(int x,int y)
    74 {
    75   Markroot(x);Pushdown(x);Access(y);Splay(y);R(y)=0;Up(y);
    76   return y;
    77 }
    78 int main()
    79 {
    80   cin>>n;int x,y;mmax[0]=-INF;
    81   for(int i=1;i<n;i++) scanf("%d %d",&x,&y),Link(x,y);
    82   for(int i=1;i<=n;i++) scanf("%d",&x),Change(i,x);
    83   cin>>m;
    84   char s[100];
    85   while(m--)
    86   {
    87     scanf("%s %d %d",s+1,&x,&y);
    88     switch(s[2])
    89     {
    90       case 'H':Change(x,y);break;
    91       case 'M':printf("%d
    ",mmax[F(x,y)]);break;
    92       case 'S':printf("%d
    ",sum[F(x,y)]);break;
    93     }
    94   }
    95   return 0;
    96 }
    LCT
  • 相关阅读:
    线程唤醒
    以前、现在
    黑马程序员训练营基础测试
    流程图
    线程同步
    Thread联系
    Java线程
    Java中文件流笔记
    字符串习题
    匿名内部类
  • 原文地址:https://www.cnblogs.com/ofsxb/p/5216399.html
Copyright © 2020-2023  润新知