树链剖分

  • 模板题

    bzoj1036

  1 #include<stdio.h>
  2 #include<algorithm>
  3 using namespace std;
  4 
  5 #define lson rt<<1,l,mid
  6 #define rson rt<<1|1,mid+1,r
  7 #define maxn 30005
  8 #define inf 0x3f3f3f3f
  9 struct node{
 10     int sum,max;
 11 }tree[maxn<<2];
 12 int cnt,v[maxn<<1],w[maxn<<1],next[maxn<<1],first[maxn];
 13 int nn,size[maxn],son[maxn],dep[maxn],fa[maxn],top[maxn],Map[maxn];
 14 
 15 void add(int st,int end){
 16     v[++cnt]=end;
 17     next[cnt]=first[st];
 18     first[st]=cnt;
 19 }
 20 void dfs(int sss){
 21     size[sss]=1;
 22     son[sss]=0;
 23     for(int e=first[sss];e;e=next[e]){
 24         if(v[e]!=fa[sss]){
 25             fa[v[e]]=sss;
 26             dep[v[e]]=dep[sss]+1;
 27             dfs(v[e]);
 28             if(size[v[e]]>size[son[sss]])son[sss]=v[e];
 29             size[sss]+=size[v[e]];
 30         }
 31     }
 32 }
 33 void build(int sss,int anc){
 34     Map[sss]=++nn;top[sss]=anc;
 35     if(son[sss])build(son[sss],anc);
 36     for(int e=first[sss];e;e=next[e])
 37         if(v[e]!=fa[sss]&&v[e]!=son[sss])
 38             build(v[e],v[e]);
 39 }
 40 void update(int rt,int l,int r,int pos,int x){
 41     if(l==r){
 42         tree[rt].max=tree[rt].sum=x;
 43         return;
 44     }
 45     int mid=(l+r)>>1;
 46     if(pos<=mid)update(lson,pos,x);
 47     else update(rson,pos,x);
 48     tree[rt].max=max(tree[rt<<1].max,tree[rt<<1|1].max);
 49     tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
 50 }
 51 int sec_max(int rt,int l,int r,int ql,int qr){
 52     if(ql<=l&&qr>=r)return tree[rt].max;
 53     int ans=-inf,mid=(l+r)>>1;
 54     if(ql<=mid)ans=max(ans,sec_max(lson,ql,qr));
 55     if(qr>mid)ans=max(ans,sec_max(rson,ql,qr));
 56     return ans;
 57 }
 58 int max_op(int va,int vb){
 59     int ans=-inf,f1=top[va],f2=top[vb];
 60     while(f1!=f2){
 61         if(dep[f1]<dep[f2])swap(f1,f2),swap(va,vb);
 62         ans=max(ans,sec_max(1,1,nn,Map[f1],Map[va]));
 63         va=fa[f1];f1=top[va];
 64     }
 65     if(dep[va]>dep[vb])swap(va,vb);
 66     return max(ans,sec_max(1,1,nn,Map[va],Map[vb]));
 67 }
 68 int query(int rt,int l,int r,int ql,int qr){
 69     if(ql<=l&&qr>=r)return tree[rt].sum;
 70     int ans=0,mid=(l+r)>>1;
 71     if(ql<=mid)ans+=query(lson,ql,qr);
 72     if(qr>mid)ans+=query(rson,ql,qr);
 73     return ans;
 74 }
 75 int sum_op(int va,int vb){
 76     int ans=0,f1=top[va],f2=top[vb];
 77     while(f1!=f2){
 78         if(dep[f1]<dep[f2])swap(f1,f2),swap(va,vb);
 79         ans+=query(1,1,nn,Map[f1],Map[va]);
 80         va=fa[f1];f1=top[va];
 81     }
 82     if(dep[va]>dep[vb])swap(va,vb);
 83     return ans+query(1,1,nn,Map[va],Map[vb]);
 84 }
 85 int main(){
 86     int n,x,q,a,b;
 87     scanf("%d",&n);
 88     for(int i=1;i<n;i++){
 89         scanf("%d%d",&a,&b);
 90         add(a,b);add(b,a);
 91     }
 92     dfs(1);
 93     build(1,1);
 94     for(int i=1;i<=n;i++){
 95         scanf("%d",&x);
 96         update(1,1,nn,Map[i],x);
 97     }
 98     scanf("%d",&q);
 99     for(int i=1;i<=q;i++){
100         char op[15];
101         scanf("%s%d%d",op,&a,&b);
102         if(op[0]=='C')update(1,1,nn,Map[a],b);
103         else{
104             if(op[1]=='M')printf("%d
",max_op(a,b));
105             else printf("%d
",sum_op(a,b));
106         }
107     }
108     return 0;
109 }
View Code
  • 坑B题

    bzoj2243

  1 #include<stdio.h>
  2 #include<algorithm>
  3 using namespace std;
  4 
  5 #define maxn 100005
  6 #define lson rt<<1,l,mid
  7 #define rson rt<<1|1,mid+1,r
  8 struct node{
  9     int sum,lc,rc,mark;
 10 }tree[maxn<<2];
 11 int cnt,v[maxn<<1],next[maxn<<1],first[maxn];
 12 int nn,lcol,rcol,col[maxn],size[maxn],son[maxn],dep[maxn],fa[maxn],bel[maxn],Map[maxn],top[maxn];
 13 
 14 void add(int st,int end){
 15     v[++cnt]=end;
 16     next[cnt]=first[st];
 17     first[st]=cnt;
 18 }
 19 
 20 void dfs(int sss){
 21     size[sss]=1;
 22     son[sss]=0;
 23     for(int e=first[sss];e;e=next[e]){
 24         if(v[e]!=fa[sss]){
 25             fa[v[e]]=sss;
 26             dep[v[e]]=dep[sss]+1;
 27             dfs(v[e]);
 28             if(size[v[e]]>size[son[sss]])son[sss]=v[e];
 29             size[sss]+=size[v[e]];
 30         }
 31     }
 32 }
 33 
 34 void hash(int sss,int anc){
 35     Map[sss]=++nn;bel[nn]=sss;top[sss]=anc;
 36     if(son[sss])hash(son[sss],anc);
 37     for(int e=first[sss];e;e=next[e])
 38         if(v[e]!=fa[sss]&&v[e]!=son[sss])hash(v[e],v[e]);
 39 }
 40 
 41 void push_up(int rt){
 42     tree[rt].lc=tree[rt<<1].lc;
 43     tree[rt].rc=tree[rt<<1|1].rc;
 44     tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum-(tree[rt<<1].rc==tree[rt<<1|1].lc);
 45 }
 46 
 47 void push_down(int rt){
 48     if(tree[rt].mark!=-1){
 49         tree[rt<<1].lc=tree[rt<<1].rc=tree[rt<<1].mark=tree[rt].mark;
 50         tree[rt<<1|1].lc=tree[rt<<1|1].rc=tree[rt<<1|1].mark=tree[rt].mark;
 51         tree[rt<<1].sum=tree[rt<<1|1].sum=1;
 52         tree[rt].mark=-1;
 53     }
 54 }
 55 
 56 void build(int rt,int l,int r){
 57     tree[rt].mark=-1;
 58     if(l==r){
 59         tree[rt].lc=tree[rt].rc=col[bel[l]];
 60         tree[rt].sum=1;
 61         return;
 62     }
 63     int mid=(l+r)>>1;
 64     build(lson);build(rson);
 65     push_up(rt);
 66 }
 67 
 68 int query(int rt,int l,int r,int ql,int qr){
 69     if(l==ql)lcol=tree[rt].lc;
 70     if(r==qr)rcol=tree[rt].rc;
 71     if(ql<=l&&qr>=r)return tree[rt].sum;
 72     push_down(rt);
 73     int ans=0,t1=-1,t2=-1,mid=(l+r)>>1;
 74     if(ql<=mid)ans+=query(lson,ql,qr),t1=tree[rt<<1].rc;
 75     if(qr>mid)ans+=query(rson,ql,qr),t2=tree[rt<<1|1].lc;
 76     ans-=(t1==t2&&t1!=-1);
 77     return ans;
 78 }
 79 
 80 int query_op(int va,int vb){
 81     int ans=0,t1=-1,t2=-1,f1=top[va],f2=top[vb];
 82     while(f1!=f2){
 83         if(dep[f1]<dep[f2])swap(f1,f2),swap(va,vb),swap(t1,t2);
 84         ans+=(query(1,1,nn,Map[f1],Map[va])-(t1==rcol));
 85         t1=lcol;
 86         va=fa[f1];f1=top[va];
 87     }
 88     if(dep[va]<dep[vb])swap(va,vb),swap(t1,t2);//important
 89     ans+=(query(1,1,nn,Map[vb],Map[va])-(t1==rcol&&t1!=-1)-(t2==lcol&&t2!=-1));
 90     return ans;
 91 }
 92 
 93 void update(int rt,int l,int r,int ql,int qr,int c){
 94     if(ql<=l&&qr>=r){
 95         tree[rt].lc=tree[rt].rc=tree[rt].mark=c;
 96         tree[rt].sum=1;
 97         return;
 98     }
 99     push_down(rt);
100     int mid=(l+r)>>1;
101     if(ql<=mid)update(lson,ql,qr,c);
102     if(qr>mid)update(rson,ql,qr,c);
103     push_up(rt);
104 }
105 
106 void update_op(int va,int vb,int c){
107     int f1=top[va],f2=top[vb];
108     while(f1!=f2){
109         if(dep[f1]<dep[f2])swap(f1,f2),swap(va,vb);
110         update(1,1,nn,Map[f1],Map[va],c);
111         va=fa[f1];f1=top[va];
112     }
113     if(dep[va]>dep[vb])swap(va,vb);
114     update(1,1,nn,Map[va],Map[vb],c);
115 }
116 
117 int main(){
118     freopen("1.in","r",stdin);
119     int n,m,a,b,c;
120     scanf("%d%d",&n,&m);
121     for(int i=1;i<=n;i++)
122         scanf("%d",&col[i]);
123     for(int i=1;i<n;i++){
124         scanf("%d%d",&a,&b);
125         add(a,b);add(b,a);
126     }
127     dfs(1);
128     hash(1,1);
129     build(1,1,nn);
130     for(int i=1;i<=m;i++){
131         char op[5];
132         scanf("%s%d%d",op,&a,&b);
133         if(op[0]=='Q') printf("%d
",query_op(a,b));
134         else {
135             scanf("%d",&c);
136             update_op(a,b,c);
137         }
138     }
139     return 0;
140 }
View Code

    永远的痛,注释里的important,老夫没有注意到这道题的特殊性质,于是这一行还是按上道题内种方式写的,于是BOOM

由于是在恶补知识点之前学的,所以并没有老爷题yoooo~

原文地址:https://www.cnblogs.com/Ngshily/p/4981337.html