zoukankan      html  css  js  c++  java
  • COJ 1008 WZJ的数据结构(八) 树上操作

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=986

    WZJ的数据结构(八)
    难度级别:E; 运行时间限制:3000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
    试题描述
     

    给你一个N个节点的森林,从1到N编号,每个点有权值。请你设计一个数据结构,进行以下两种操作:

    1.修改:给你a、b、c,将a到b路径上所有点的权值改成c。

    2.增加:给你a、b、c,将a到b路径上所有点的权值增加c。

    3.询问:给你a、b,输出从a到b路径上经过所有点权值的最大值、最小值与权值和。

     
    输入
    第一行为一个正整数N。
    接下来N-1行为每一条边,每行2个正整数a,b,表示有一条从a到b的边(从1开始编号)。
    第N+1行为n个正整数Ai,表示每个点的开始权值。
    第N+2行为一个正整数Q,表示Q次操作。
    接下来Q行为每一次询问,每行3或4个正整数(t)、a、b、c。 
    若t=0表示修改,t=1表示增加,t=2表示查询。
    输出
    对于每一次询问,输出结果。
    输入示例
    5
    1 2
    1 3
    2 5
    5 4
    1 3 2 3 5
    5
    2 1 5
    2 3 4
    0 3 5 2
    1 1 4 1
    2 3 4
    输出示例
    5 1 9
    5 1 14
    4 2 15
    其他说明
    1<=N<=100000
    1<=Q<=100000
    1<=Ai<=1000
    1<=a,b<=N 1<=c<=1000

    题解:树链剖分直接套上1010好了。。。

    更新:指针的线段树+邻接表:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 #define CH for(int d=0;d<=1;d++) if(ch[d])
     10 #define lson x->ch[0],L,M
     11 #define rson x->ch[1],M+1,R
     12 using namespace std;
     13 const int maxn=100000+10,inf=-1u>>1;
     14 struct node{
     15     node*ch[2];int mx,mi,sm,set,add,siz;
     16     node(){set=inf;add=0;}
     17     void init(int t){mi=mx=sm=t;return;}
     18     void addt(int tag){
     19         mi+=tag;mx+=tag;sm+=tag*siz;add+=tag;return;
     20     }
     21     void sett(int tag){
     22         add=0;mi=mx=set=tag;sm=siz*tag;return;
     23     }
     24     void update(){
     25         mi=inf;mx=-inf;sm=0;
     26         CH{mi=min(mi,ch[d]->mi);mx=max(mx,ch[d]->mx);sm+=ch[d]->sm;}
     27         return;
     28     }
     29     void down(){
     30         if(set!=inf){CH{ch[d]->sett(set);}set=inf;}
     31         if(add){CH{ch[d]->addt(add);}add=0;}
     32         return;
     33     }
     34 }seg[maxn<<1],*nodecnt=seg,*root;
     35 int A[maxn],n,Q,ql,qr,cv,tp,_mi,_mx,_sm;
     36 void build(node*&x,int L,int R){
     37     x=nodecnt++;
     38     if(L==R) x->init(A[L]);
     39     else{
     40         int M=L+R>>1;
     41         build(lson);build(rson);
     42         x->update();
     43     } x->siz=R-L+1;return;
     44 }
     45 void update(node*&x,int L,int R){
     46     if(ql<=L&&R<=qr){
     47         if(tp) x->addt(cv);
     48         else x->sett(cv);
     49     }else{
     50         int M=L+R>>1;
     51         x->down();
     52         if(ql<=M) update(lson);
     53         if(qr>M) update(rson);
     54         x->update();
     55     } return;
     56 }
     57 void query(node*x,int L,int R){
     58     if(ql<=L&&R<=qr){
     59         _mi=min(_mi,x->mi);
     60         _mx=max(_mx,x->mx);
     61         _sm+=x->sm;
     62     }else{
     63         int M=L+R>>1;
     64         x->down();
     65         if(ql<=M) query(lson);
     66         if(qr>M) query(rson);
     67     } return;
     68 }
     69 struct ted{int x,y;ted*nxt;}adj[maxn<<1],*fch[maxn],*ms=adj;
     70 void ade(int x,int y){
     71     *ms=(ted){x,y,fch[x]};fch[x]=ms++;
     72     *ms=(ted){y,x,fch[y]};fch[y]=ms++;
     73     return;
     74 }
     75 int dep[maxn],p[maxn],son[maxn],top[maxn],siz[maxn],fa[maxn],cz=0;
     76 void dfs(int x){
     77     siz[x]=1;dep[x]=dep[fa[x]]+1;
     78     for(ted*e=fch[x];e;e=e->nxt){
     79         int v=e->y;if(v!=fa[x]){
     80             fa[v]=x;dfs(v);siz[x]+=siz[v];
     81             if(siz[son[x]]<siz[v]) son[x]=v;
     82         }
     83     } return;
     84 }
     85 void build(int x,int tp){
     86     p[x]=++cz;top[x]=tp;
     87     if(son[x]) build(son[x],tp);
     88     for(ted*e=fch[x];e;e=e->nxt){
     89         int v=e->y;
     90         if(v!=fa[x]&&v!=son[x]) build(v,v);
     91     } return;
     92 }
     93 void update(int x,int y){
     94     int f1=top[x],f2=top[y];
     95     while(f1!=f2){
     96         if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
     97         ql=p[f1];qr=p[x];update(root,1,n);
     98         x=fa[f1];f1=top[x];
     99     } if(dep[x]>dep[y]) swap(x,y);
    100     ql=p[x];qr=p[y];update(root,1,n);return;
    101 }
    102 void query(int x,int y){
    103     int f1=top[x],f2=top[y];
    104     while(f1!=f2){
    105         if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
    106         ql=p[f1];qr=p[x];query(root,1,n);
    107         x=fa[f1];f1=top[x];
    108     } if(dep[x]>dep[y]) swap(x,y);
    109     ql=p[x];qr=p[y];query(root,1,n);return;
    110 }
    111 inline int read(){
    112     int x=0,sig=1;char ch=getchar();
    113     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    114     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    115     return x*=sig;
    116 }
    117 inline void write(int x){
    118     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    119     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    120     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    121 }
    122 void init(){
    123     n=read();
    124     for(int i=1;i<n;i++) ade(read(),read());
    125     dfs(1);build(1,1);
    126     for(int i=1;i<=n;i++) A[p[i]]=read();
    127     build(root,1,n);
    128     return;
    129 }
    130 void work(){
    131     Q=read();int x,y;
    132     while(Q--){
    133         tp=read();x=read();y=read();
    134         if(tp!=2) cv=read(),update(x,y);
    135         else{
    136             _mi=inf;_mx=-inf;_sm=0;query(x,y);
    137             write(_mx);PAU;write(_mi);PAU;write(_sm);ENT;
    138         }
    139     }
    140     return;
    141 }
    142 void print(){
    143     return;
    144 }
    145 int main(){init();work();print();return 0;}

    数组线段树:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 using namespace std;
     10 const int maxn=100000+10,maxn3=300000+10,inf=-1u>>1;
     11 struct Tedge{int x,y,next;}adj[maxn*2];int ms=0,fch[maxn];
     12 int n,Q;
     13 void AddEdge(int v,int u){
     14     adj[++ms]=(Tedge){u,v,fch[u]};fch[u]=ms;
     15     adj[++ms]=(Tedge){v,u,fch[v]};fch[v]=ms;
     16     return;
     17 }
     18 int maxv[maxn3],minv[maxn3],sumv[maxn3],setv[maxn3],addv[maxn3],A[maxn];
     19 void pushup(int o,int lc,int rc){
     20     minv[o]=min(minv[lc],minv[rc]);
     21     maxv[o]=max(maxv[lc],maxv[rc]);
     22     sumv[o]=sumv[lc]+sumv[rc];
     23     return;
     24 }
     25 void pushdown(int o,int lc,int rc){
     26     if(setv[o]>=0){
     27         setv[lc]=setv[rc]=setv[o];
     28         addv[lc]=addv[rc]=0;
     29         setv[o]=-1;
     30     } if(addv[o]){
     31         addv[lc]+=addv[o];
     32         addv[rc]+=addv[o];
     33         addv[o]=0;
     34     } return;
     35 }
     36 void maintain(int o,int L,int R){
     37     int lc=o<<1,rc=lc|1;
     38     if(L<R&&setv[o]<0) pushup(o,lc,rc);
     39     if(setv[o]>=0){
     40         minv[o]=maxv[o]=setv[o];
     41         sumv[o]=(R-L+1)*setv[o];
     42     } if(addv[o]){
     43         minv[o]+=addv[o];
     44         maxv[o]+=addv[o];
     45         sumv[o]+=(R-L+1)*addv[o];
     46     } return;
     47 }
     48 int _min,_max,_sum,ql,qr,tp,cv;
     49 void update(int o,int L,int R){
     50     if(ql<=L&&R<=qr){
     51         if(tp) addv[o]+=cv;
     52         else setv[o]=cv,addv[o]=0;
     53     } else{
     54         int M=L+R>>1,lc=o<<1,rc=lc|1;
     55         pushdown(o,lc,rc);
     56         if(ql<=M) update(lc,L,M); else maintain(lc,L,M);
     57         if(qr>M) update(rc,M+1,R); else maintain(rc,M+1,R);
     58     } maintain(o,L,R);return;
     59 }
     60 void build(int o,int L,int R){
     61     if(L==R) setv[o]=A[L];
     62     else{
     63         int M=L+R>>1,lc=o<<1,rc=lc|1;
     64         build(lc,L,M);build(rc,M+1,R);
     65     } maintain(o,L,R);return;
     66 }
     67 void query(int o,int L,int R,int add){
     68     if(setv[o]>=0){
     69         int change=setv[o]+addv[o]+add;
     70         _sum+=(min(R,qr)-max(L,ql)+1)*change;
     71         _min=min(_min,change);
     72         _max=max(_max,change);
     73     } else if(ql<=L&&R<=qr){
     74         _sum+=sumv[o]+(R-L+1)*add;
     75         _min=min(_min,minv[o]+add);
     76         _max=max(_max,maxv[o]+add);
     77     } else{
     78         int M=L+R>>1,lc=o<<1,rc=lc|1;
     79         if(ql<=M) query(lc,L,M,add+addv[o]);
     80         if(M<qr) query(rc,M+1,R,add+addv[o]);
     81     } return;
     82 }
     83 int dep[maxn],siz[maxn],top[maxn],p[maxn],fa[maxn],son[maxn];
     84 void dfs(int u){
     85     siz[u]=1;dep[u]=dep[fa[u]]+1;
     86     for(int i=fch[u];i;i=adj[i].next){
     87         int v=adj[i].y;
     88         if(v!=fa[u]){
     89             fa[v]=u;dfs(v);
     90             if(siz[son[u]]<siz[v]) son[u]=v;
     91             siz[u]+=siz[v];
     92         }
     93     } return;
     94 }
     95 int cz=0;
     96 void build(int u,int tp){
     97     p[u]=++cz;top[u]=tp;
     98     if(son[u]) build(son[u],tp);
     99     for(int i=fch[u];i;i=adj[i].next){
    100         int v=adj[i].y;
    101         if(v!=fa[u]&&v!=son[u]) build(v,v);
    102     } return;
    103 }
    104 void query(int a,int b){
    105     int f1=top[a],f2=top[b];
    106     while(f1!=f2){
    107         if(dep[f1]<dep[f2]) swap(a,b),swap(f1,f2);
    108         ql=p[f1];qr=p[a];query(1,1,n,0);
    109         a=fa[f1];f1=top[a];
    110     }
    111     if(dep[a]>dep[b]) swap(a,b);
    112     ql=p[a];qr=p[b];query(1,1,n,0);return;
    113 }
    114 void update(int a,int b){
    115     int f1=top[a],f2=top[b];
    116     while(f1!=f2){
    117         if(dep[f1]<dep[f2]) swap(a,b),swap(f1,f2);
    118         ql=p[f1];qr=p[a];update(1,1,n);
    119         a=fa[f1];f1=top[a];
    120     }
    121     if(dep[a]>dep[b]) swap(a,b);
    122     ql=p[a];qr=p[b];update(1,1,n);return;
    123 }
    124 inline int read(){
    125     int x=0,sig=1;char ch=getchar();
    126     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    127     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    128     return x*=sig;
    129 }
    130 inline void write(int x){
    131     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    132     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    133     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    134 }
    135 void init(){
    136     memset(setv,-1,sizeof(setv));
    137     n=read();
    138     for(int i=1;i<n;i++) AddEdge(read(),read());
    139     dfs(1);build(1,1);
    140     for(int i=1;i<=n;i++) A[p[i]]=read();//这么写跑的更快 
    141     build(1,1,n);
    142     /*for(int i=1;i<=n;i++){//这样慢 
    143         ql=qr=p[i];cv=read();
    144         update(1,1,n);
    145     }*/
    146     Q=read();
    147     return;
    148 }
    149 void work(){
    150     int a,b;
    151     while(Q--){
    152         tp=read();a=read();b=read();
    153         if(tp==2){//query
    154             _sum=0;_min=inf;_max=-inf;
    155             query(a,b);
    156             write(_max);PAU;write(_min);PAU;write(_sum);ENT;
    157         } else cv=read(),update(a,b);
    158     }
    159     return;
    160 }
    161 void print(){
    162     return;
    163 }
    164 int main(){init();work();print();return 0;}

     大数据跑LCT还是快:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 using namespace std;
     10 const int maxn=100000+10,inf=-1u>>1;
     11 inline int read(){
     12     int x=0,sig=1;char ch=getchar();
     13     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
     14     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
     15     return x*=sig;
     16 }
     17 inline void write(int x){
     18     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
     19     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
     20     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
     21 }
     22 struct node {
     23     node *ch[2],*fa;
     24     bool rev;
     25     int x,sm,siz,add,mi,mx,set;
     26     inline void add_rev_tag(){
     27         swap(ch[0],ch[1]);rev^=1;return;
     28     }
     29     inline void add_plus_tag(int a){
     30         sm+=siz*a;x+=a;add+=a;
     31         if(mi!=inf) mi+=a;
     32         if(mx!=-inf) mx+=a;
     33         return;
     34     }
     35     inline void add_set_tag(int a){
     36         x=set=a;add=0;sm=a*siz;
     37         if(mi!=inf) mi=set;
     38         if(mx!=-inf) mx=set;
     39     }
     40     inline void down(){
     41         if(rev){
     42             if(ch[0]) ch[0]->add_rev_tag();
     43             if(ch[1]) ch[1]->add_rev_tag();
     44             rev=0;
     45         }
     46         if(set){
     47             if(ch[0]) ch[0]->add_set_tag(set);
     48             if(ch[1]) ch[1]->add_set_tag(set);
     49             set=0;
     50         }
     51         if(add){
     52             if(ch[0]) ch[0]->add_plus_tag(add);
     53             if(ch[1]) ch[1]->add_plus_tag(add);
     54             add=0;
     55         }
     56         return;
     57     }
     58     inline void update(){
     59         sm=0;siz=1;mi=inf;mx=-inf;
     60         if(ch[0]) sm+=ch[0]->sm,siz+=ch[0]->siz,mi=min(mi,ch[0]->mi),mx=max(mx,ch[0]->mx);
     61         if(ch[1]) sm+=ch[1]->sm,siz+=ch[1]->siz,mi=min(mi,ch[1]->mi),mx=max(mx,ch[1]->mx);
     62         if(!x) return;
     63         mi=min(x,mi);
     64         mx=max(x,mx);
     65         sm+=x;
     66         return;
     67     }
     68 }lct[maxn];
     69 inline int get_parent(node *x,node *&fa){return (fa=x->fa)?fa->ch[0]==x?0:fa->ch[1]==x?1:-1:-1;}
     70 inline void rotate(node *x){
     71     int t1,t2;
     72     node *fa,*gfa;
     73     t1=get_parent(x,fa);
     74     t2=get_parent(fa,gfa);
     75     if ((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa;
     76     x->ch[t1^1]=fa;fa->fa=x;x->fa=gfa;
     77     if (t2!=-1) gfa->ch[t2]=x;
     78     fa->update();return;
     79 }
     80 inline void pushdown(node *x){
     81     static node *stack[maxn];
     82     int cnt=0;
     83     while(1){
     84         stack[cnt++]=x;
     85         node *fa=x->fa;
     86         if (!fa || (fa->ch[0]!=x && fa->ch[1]!=x)) break;
     87         x=fa;
     88     }
     89     while(cnt--) stack[cnt]->down();
     90     return;
     91 }
     92 inline node * splay(node *x){
     93     pushdown(x);
     94     while(1){
     95         int t1,t2;
     96         node *fa,*gfa;
     97         t1=get_parent(x,fa);
     98         if(t1==-1) break;
     99         t2=get_parent(fa,gfa);
    100         if(t2==-1){
    101             rotate(x);break;
    102         } else if (t1==t2){
    103             rotate(fa);rotate(x);
    104         } else{
    105             rotate(x);rotate(x);
    106         }
    107     }
    108     x->update();
    109     return x;
    110 }
    111 inline node * access(node *x){
    112     node *ret=NULL;
    113     while (x) splay(x)->ch[1]=ret,(ret=x)->update(),x=x->fa;
    114     return ret;
    115 }
    116 inline void makeroot(int x){access(lct+x)->add_rev_tag();}
    117 inline void link(int u,int v){
    118     makeroot(u);splay(lct+u)->fa=lct+v;return;
    119 }
    120 inline void cut(int u,int v){
    121     makeroot(u);
    122     node *p=(access(lct+v),splay(lct+v));
    123     p->ch[0]->fa=NULL;
    124     p->ch[0]=NULL;
    125     p->update();
    126 }
    127 int n,q;
    128 int main(){
    129     n=read();
    130     int i;
    131     for(i=1;i<=n;i++){
    132         lct[i].x=lct[i].sm=0;
    133         lct[i].siz=1;
    134         lct[i].add=0;
    135         lct[i].mi=inf;
    136         lct[i].mx=-inf;
    137         lct[i].set=0;
    138     }
    139     for(i=1;i<n;i++){
    140         int u,v;
    141         u=read();v=read();
    142         link(u,v);
    143     }
    144     for(int i=1;i<=n;i++){
    145         lct[i].x=read();lct[i].update();
    146     }
    147     q=read();
    148     int x,y,c;
    149     while(q--){
    150         c=read();x=read();y=read();
    151         if(c==0) makeroot(x),access(y+lct)->add_set_tag(read());
    152         else if(c==1) makeroot(x),access(y+lct)->add_plus_tag(read());
    153         else{
    154             makeroot(x);node*t=access(y+lct);splay(t);
    155             write(t->mx);PAU;write(t->mi);PAU;write(t->sm);ENT;
    156         }
    157     }
    158     return 0;
    159 }
  • 相关阅读:
    JQuery脚本-通过禁用按钮防止表单重复提交
    获得图片的圆形头像效果
    jquery通过submit()和serialize()提交表单
    nginx location 配置阐述优先级别使用说明
    友盟(Swift)-集成、统计用户数量、具体页面访问数量、具体按钮点击数量
    点击按钮,使按钮进行左右翻转动画
    清除指定区域
    语音播报-文字转系统声音
    颜色线性渐变-CAGradientLayer
    popover带箭头弹框
  • 原文地址:https://www.cnblogs.com/chxer/p/4474009.html
Copyright © 2011-2022 走看看