1036: [ZJOI2008]树的统计Count
树链剖分 模板题:
和线段树一起写各种bug:
1 #include<stdio.h> 2 #include<algorithm> 3 #include<math.h> 4 #include<vector> 5 #include<string.h> 6 #include<string> 7 #include<set> 8 #include<iostream> 9 using namespace std; 10 typedef long long ll; 11 #define N 33333 12 13 int head[N],top[N],fa[N],tot; 14 15 int son[N],p[N],fp[N],dep[N],pos; 16 int sz[N]; 17 18 void init() 19 { 20 tot=0; 21 memset(head,-1,sizeof(head)); 22 memset(son,-1,sizeof(son)); 23 pos=0; 24 } 25 26 struct node 27 { 28 int v,next; 29 }e[N<<1]; 30 31 void add(int u,int v) 32 { 33 e[tot].v=v; 34 e[tot].next=head[u]; 35 head[u]=tot++; 36 } 37 38 void dfs(int u,int f,int d) 39 { 40 dep[u]=d; 41 fa[u]=f; 42 sz[u]=1; 43 44 for (int i=head[u];i!=-1;i=e[i].next) 45 { 46 int v=e[i].v; 47 if (v==f) continue; 48 dfs(v,u,d+1); 49 sz[u]+=sz[v]; 50 if (son[u]==1||sz[son[u]]<sz[v]) son[u]=v; 51 } 52 } 53 54 void getpos(int u,int sp) 55 { 56 top[u]=sp; 57 p[u]=++pos; 58 fp[pos]=u; 59 if (son[u]==-1) return; 60 getpos(son[u],sp); 61 for (int i=head[u];i!=-1;i=e[i].next) 62 { 63 int v=e[i].v; 64 if (v!=son[u]&&v!=fa[u]) 65 getpos(v,v); 66 } 67 } 68 69 struct node2 70 { 71 int l,r,Max,sum; 72 }tree[N<<2]; 73 74 75 void pushup(int rt) 76 { 77 tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max); 78 tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum; 79 } 80 81 82 void build(int l,int r,int rt) 83 { 84 tree[rt].l=l; 85 tree[rt].r=r; 86 tree[rt].Max=tree[rt].sum=0; 87 88 if (l==r) return ; 89 int m=(l+r)>>1; 90 build(l,m,rt<<1); 91 build(m+1,r,rt<<1|1); 92 } 93 94 void update(int pos,int x,int l,int r,int rt) 95 { 96 if (l==r) 97 { 98 tree[rt].Max=tree[rt].sum=x; 99 return; 100 } 101 int m=(l+r)>>1; 102 if (pos<=m) update(pos,x,l,m,rt<<1); 103 else update(pos,x,m+1,r,rt<<1|1); 104 pushup(rt); 105 } 106 107 int querymax(int l,int r,int rt) 108 { 109 if (tree[rt].l>=l&&tree[rt].r<=r) 110 return tree[rt].Max; 111 int m=(tree[rt].l+tree[rt].r)>>1; 112 113 if (r<=m) return querymax(l,r,rt<<1); 114 else if (l>m) return querymax(l,r,rt<<1|1); 115 else return max(querymax(l,m,rt<<1),querymax(m+1,r,rt<<1|1)); 116 } 117 118 119 int querysum(int l,int r,int rt) 120 { 121 if (tree[rt].l>=l&&tree[rt].r<=r) 122 return tree[rt].sum; 123 124 int m=(tree[rt].l+tree[rt].r)>>1; 125 if (r<=m) return querysum(l,r,rt<<1); 126 else if (l>m) return querysum(l,r,rt<<1|1); 127 else return querysum(l,m,rt<<1)+querysum(m+1,r,rt<<1|1); 128 } 129 130 int Sum,Max; 131 132 void lca(int u,int v) 133 { 134 int fu=top[u]; 135 int fv=top[v]; 136 Sum=0; 137 Max=-24242554; 138 while (fu!=fv) 139 { 140 if (dep[fu]<dep[fv]) 141 { 142 swap(fu,fv); 143 swap(u,v); 144 } 145 146 Max=max(Max,querymax(p[fu],p[u],1)); 147 Sum+=querysum(p[fu],p[u],1); 148 u=fa[fu]; 149 fu=top[u]; 150 } 151 152 if (dep[u]>dep[v]) swap(u,v); 153 Max=max(Max,querymax(p[u],p[v],1)); 154 Sum+=querysum(p[u],p[v],1); 155 156 //Max=max(Max,querymax(p[fa[u]],p[v],1)); 157 //Sum+=querysum(p[fa[u]],p[v],1); 158 } 159 int a[N]; 160 161 int main() 162 { 163 int n; 164 scanf("%d",&n); 165 init(); 166 for (int i=1;i<n;i++) 167 { 168 int x,y; 169 scanf("%d%d",&x,&y); 170 add(x,y); 171 add(y,x); 172 } 173 dfs(1,0,0); 174 getpos(1,1); 175 build(1,pos,1); 176 177 for (int i=1;i<=n;i++) scanf("%d",&a[i]),update(p[i],a[i],1,pos,1); 178 179 int Q; 180 scanf("%d",&Q); 181 while (Q--) 182 { 183 char s[10]; 184 int x,y; 185 scanf("%s",s); 186 scanf("%d%d",&x,&y); 187 if (s[0]=='C') update(p[x],y,1,pos,1); 188 else 189 { 190 lca(x,y); 191 if (s[1]=='M') printf("%d\n",Max); 192 else printf("%d\n",Sum); 193 } 194 } 195 196 return 0; 197 }
随性Code