SPOJ 6779 Can you answer these queries VII 树链剖分
来源:互联网 发布:四川遂宁广电网络 编辑:程序博客网 时间:2024/05/21 15:50
题目大意:给一颗树,树上每个节点都有一个权。两种操作,1 l r:询问l到r路径上所有点权组成的串的最大子串和;2 l r c:将l到r路径上的所有点权改为c。
思路:如果不是树,那么就基本和SPOJ 1043一样。但是题目是树,这里采用树链剖分。
//#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<cmath>#include<cctype>#include<string>#include<algorithm>#include<iostream>#include<ctime>#include<map>#include<set>using namespace std;#define MP(x,y) make_pair((x),(y))#define PB(x) push_back(x)typedef long long LL;//typedef unsigned __int64 ULL;/* ****************** */const int INF=100011122;const double INFF=1e100;const double eps=1e-8;const LL mod=1000000007;const int NN=100010;const int MM=1000010;/* ****************** */struct TR{ int l,r,sum,fg; bool ok; int l_r,r_l,maxll; int mid() { return (l+r)>>1; }}tr[NN*4];int a[NN],b[NN];struct G{ int v,next;}E[NN*2];int p[NN],T;//c_dfs1int deep[NN],si[NN],per[NN],anc[NN];//c_dfs2int tsp,pos[NN],top[NN];void add(int u,int v){ E[T].v=v; E[T].next=p[u]; p[u]=T++;}void c_dfs1(int u,int fa,int cen){ anc[u]=fa; deep[u]=cen; si[u]=1; per[u]=-1; int i,v; for(i=p[u];i+1;i=E[i].next) { v=E[i].v; if(v==fa)continue; c_dfs1(v,u,cen+1); si[u]+=si[v]; if(per[u]==-1 || si[v]>si[ per[u] ]) per[u]=v; }}void c_dfs2(int u,int fa,int now_top){ pos[u]=++tsp; top[u]=now_top; if(per[u]!=-1)c_dfs2(per[u],u,now_top); int i,v; for(i=p[u];i+1;i=E[i].next) { v=E[i].v; if(v==per[u] || v==fa)continue; c_dfs2(v,u,v); }}void up(TR &fa,TR &ls,TR &rs){ fa.sum=ls.sum+rs.sum; fa.maxll=max(ls.maxll,rs.maxll); fa.maxll=max(fa.maxll,ls.r_l+rs.l_r); fa.l_r=max(ls.l_r,ls.sum+rs.l_r); fa.r_l=max(rs.r_l,rs.sum+ls.r_l);}void push_up(int R){ up(tr[R],tr[R<<1],tr[R<<1|1]);}void down(int R,int col){ tr[R].fg=col; tr[R].ok=true; tr[R].sum=col*(tr[R].r-tr[R].l+1); if(col>0) { tr[R].l_r=tr[R].r_l=tr[R].maxll=tr[R].sum; } else { tr[R].l_r=tr[R].r_l=tr[R].maxll=col; }}void push_down(int R){ if(tr[R].ok) { down(R<<1,tr[R].fg); down(R<<1|1,tr[R].fg); tr[R].ok=false; }}void build(int l,int r,int R){ tr[R].l=l; tr[R].r=r; tr[R].ok=false; if(l==r) { tr[R].sum=tr[R].l_r=tr[R].r_l=tr[R].maxll=b[l]; return; } int mid=tr[R].mid(); build(l,mid,R<<1); build(mid+1,r,R<<1|1); push_up(R);}void update(int l,int r,int R,int col){ if(l<=tr[R].l && tr[R].r<=r) { down(R,col); return; } push_down(R); int mid=tr[R].mid(); if(l<=mid) update(l,r,R<<1,col); if(r>=mid+1) update(l,r,R<<1|1,col); push_up(R);}TR query(int l,int r,int R){ if(l<=tr[R].l && tr[R].r<=r) return tr[R]; push_down(R); int t=0,mid=tr[R].mid(); TR temp[3]; if(l<=mid)t++,temp[1]=query(l,r,R<<1); if(r>=mid+1)t+=2,temp[2]=query(l,r,R<<1|1); if(t<3)return temp[t]; up(temp[0],temp[1],temp[2]); return temp[0];}void c_update(int u,int v,int col){ while(top[u]!=top[v]) { if(deep[ top[u] ] > deep[ top[v] ]) swap(u,v); update(pos[ top[v] ],pos[v],1,col); v=anc[ top[v] ]; } if(pos[u]>pos[v]) swap(u,v); update(pos[u],pos[v],1,col);}int c_query(int u,int v){ int zz,yy,ans=0; TR tt; zz=yy=0; while(top[u]!=top[v]) { if(deep[ top[u] ] > deep[ top[v] ]) { // printf("check==[%d,%d]\n",pos[ top[u] ],pos[u]); tt=query(pos[ top[u] ],pos[u],1); // printf("check ok\n"); ans=max(ans,tt.maxll); ans=max(ans,zz+tt.r_l); zz=max(zz+tt.sum,tt.l_r); u=anc[ top[u] ]; } else { // printf("check==[%d,%d]\n",pos[ top[v] ],pos[v]); tt=query(pos[ top[v] ],pos[v],1); // printf("check ok\n"); ans=max(ans,tt.maxll); ans=max(ans,yy+tt.r_l); yy=max(yy+tt.sum,tt.l_r); v=anc[ top[v] ]; } } if(pos[u]>pos[v]) { swap(u,v); swap(zz,yy); } tt=query(pos[u],pos[v],1); ans=max(ans,tt.maxll); ans=max(ans,zz+tt.sum+yy); ans=max(ans,zz+tt.l_r); ans=max(ans,tt.r_l+yy); return ans;}void solve(int n,int m){ int op,l,r,c; build(1,n,1); while(m--) { scanf("%d",&op); if(op==1) { scanf("%d%d",&l,&r); c=c_query(l,r); // cout<<"ans=="; printf("%d\n",c); } else { scanf("%d%d%d",&l,&r,&c); c_update(l,r,c); } }}int main(){ int n,m,i; int u,v; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&a[i]); memset(p,-1,sizeof(p)); T=0; for(i=1;i<n;i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } c_dfs1(1,-1,0); tsp=0; c_dfs2(1,-1,1); for(i=1;i<=n;i++) { b[ pos[i] ]=a[i]; } scanf("%d",&m); solve(n,m); } return 0;}
0 0
- SPOJ 6779 Can you answer these queries VII 树链剖分
- spoj 6779. Can you answer these queries VII(树链剖分)
- SPOJ GSS7 Can you answer these queries VII
- SPOJ GSS7 Can you answer these queries VII(LCT)
- 动态树LCT(SPOJ 6779 Can you answer these queries VII)
- 【SPOJ】6779 Can you answer these queries VII 树链剖分+线段树 求树上的最大子段和
- SPOJGSS7 Can you answer these queries VII
- SPOJ Can you answer these queries V
- SPOJ-GSS7 Can you answer these queries VII(树上区间最大和)
- Spoj 6779 Can you answer these queries VII 树链剖分 在树上任意路径的最大子段和 区间修改点权
- spoj6779 Can you answer these queries VII(gss7)动态树
- spoj SPOJ 1043 Can you answer these queries I
- SPOJ/GSS3:Can you answer these queries III(线段树)
- spoj 1043 Can you answer these queries I
- spoj 1557 Can you answer these queries II
- spoj 2713 Can you answer these queries IV
- spoj 2916 Can you answer these queries V
- spoj 1716. Can you answer these queries III
- 水处理过滤器:反渗透保安过滤器主要表现
- 在PreferenceAcitity中使用Fragement时避免额外的Left和RightPadding
- 安卓res里面的drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)
- BOJ 396~400. 整合
- VC中IP地址控件的赋值与取值
- SPOJ 6779 Can you answer these queries VII 树链剖分
- WEBKIT内核源码分析系列
- 插入法排序
- 数塔
- Android Framework------之Input子系统
- Fractal poj 2083
- QtCreator 布局管理(QLayout,QBoxLayout,QGridLayout,QFormLayout,QStackedLayout)
- Wooden Sticks +hdu+贪心
- oracle全文检索