传送门: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('\n')
  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('\n')
  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('\n')
  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 }

搜索

复制

转载于:https://www.cnblogs.com/chxer/p/4474009.html

COJ 1008 WZJ的数据结构(八) 树上操作相关推荐

  1. COJ 0995 WZJ的数据结构(负五)区间操作

    WZJ的数据结构(负五) 难度级别:C: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小为 ...

  2. COJ 1006 树上操作

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=979 WZJ的数据结构(六) 难度级别:D: 运行时间限制:1000ms: ...

  3. P3178 [HAOI2015]树上操作

    P3178 [HAOI2015]树上操作 题意: 题解: 这已经是很裸的树链剖分了... 直接套模板 代码: #include<cmath> #include<cstdio> ...

  4. BZOJ4034 树上操作

    目录 BZOJ4034 树上操作 题解 code BZOJ4034 树上操作 题目传送门 题解 裸的树剖,写的时候注意细节即可. code #include <bits/stdc++.h> ...

  5. Java内存模型 - 同步八种操作

    Java 内存模型 - 同步操作与规则 Java内存模型 - 同步八种操作 锁定(lock): 作用于主内存中的变量,将他标记为一个线程独享变量. 通常意义上的上锁,就是一个线程正在使用时,其他线程必 ...

  6. BZOJ 4043 [HAOI2015]树上操作 dfs序 线段树

    $ \Rightarrow $ 戳我进BZOJ原题 $ \Rightarrow $ 戳我进洛谷原题 [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 25 ...

  7. bzoj 4034: [HAOI2015]树上操作(树链剖分+线段树区间更新)

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 4981  Solved: 1603 [Submit][St ...

  8. 【高并发】别闹了,这样理解Java的内存模型才正确(八种操作+同步规则)

    大家好,我是冰河~~ 最近冰河不是又出版了一本<深入理解高并发编程:核心原理与案例实战>一书吗?很多小伙伴对于Java的内存模型还是不太了解,今天,我就用最简短的篇幅结合八种操作和同步规则 ...

  9. 数据结构实验--平衡二叉树操作的演示

    一.题目描述 利用平衡二叉树实现一个动态查找表,实现动态查找表的三种基本功能:查找.插入和删除. 二.需求分析 1.建立平衡二叉树并进行创建.查找.插入.删除等功能. 2.设计一个实现平衡二叉树的程序 ...

最新文章

  1. 购买IBM System x3650 M4十大理由
  2. PlayMaker的Transition和Global Transition
  3. JSP内置对象(request、session、application)
  4. Linux下的socket演示程序
  5. 手把手教你如下在Linux下如何写一个C语言代码,编译并运行
  6. Java异常处理之InvocationTargetException(反射异常)
  7. 小雷:我的核心定位和远大志向(上次更新2013年11月9日)
  8. java抛出自定义异常_令Java程序员头疼的异常报错,你遇到过哪些?
  9. c++单例模式Singleton Pattern
  10. USB_CAN-2A使用CANTest解析J1939
  11. php mysql常见面试题_PHP常见面试题总结
  12. linux 基本命令及用法列子
  13. USB转串口芯片CH340系列及CH340模块使用方法(CH340驱动,接线,串口下载详细介绍)
  14. 二层广播风暴(产生原因+判断+解决)
  15. SpringBoot整合JWT实现API身份校验
  16. 李彦宏:一个人的百度
  17. 微信小程序开源Demo精选
  18. 深度解读抖音平台规则与机制
  19. PhotoShop一键标注文本图层工具
  20. tcptraceroute命令可以绕过最常见的防火墙过滤器

热门文章

  1. mysql peferences_MySQL初次实践
  2. mapper中 <include refid=“XXX“></include>标签 <sql id=“XXX“>标签
  3. 多线程一定比单线程快吗
  4. mybatis框架使用generator的快速搭建
  5. oracle form 滚动条,jQuery实现的自定义滚动条实例详解
  6. 和rna用什么鉴定_RNA-seq:测序原理之文库构建
  7. 用动态数组模拟双向循环链表
  8. windows 上ping输入到指定文件中
  9. 图像处理:像素间的基本关系
  10. 在html中选项卡怎么做,纯css3制作选项卡