小白逛公园加强版(vijos1620)
来源:互联网 发布:vmware mac补丁包 编辑:程序博客网 时间:2024/04/30 02:35
小白逛森林公园
Description
小新经常陪小白去公园玩,也就是所谓的遛狗啦……在小新家附近有n个公园,这些公园通过一些路径相连,并保证每两个公园之间有且仅有一条通路相连(也就是说这是一棵树),小白早就看花了眼,自己也不清楚该去哪些公园玩了。
小白对每个公园都有一个评价(可正可负),并且它只会让小新做两件事:
1. 询问公园a到公园b路径上最大连续公园的评价和,就是说我们把公园a到公园b路径上的公园(包括a和b)排成一条直线,那么小白希望知道一段连续的公园的评价和最大为多少。
2. 修改公园a到公园b路径上(包括a和b)每个公园的评价值。
小新现在已经处理不了n超过10的情况,因此请你来帮忙……
小白对每个公园都有一个评价(可正可负),并且它只会让小新做两件事:
1. 询问公园a到公园b路径上最大连续公园的评价和,就是说我们把公园a到公园b路径上的公园(包括a和b)排成一条直线,那么小白希望知道一段连续的公园的评价和最大为多少。
2. 修改公园a到公园b路径上(包括a和b)每个公园的评价值。
小新现在已经处理不了n超过10的情况,因此请你来帮忙……
Input
第一行有一个自然数,表示n
第二行有n个自然数,表示一开始小白对每个公园的评价(评价值的绝对值不超过10000)
下面有n-1行,每行两个数a和b,表示公园a和公园b直接由道路相连
再下面一行有一个自然数,表示m
最后m行,每行第一个数k表示要执行的操作。如果k为1,那么后面有两个自然数a和b,表示询问公园a到公园b路径上(包含a和b)最大的连续公园评价和(如果这条路径上每个公园的评价都为负数,那么最大连续和为0)。如果k为2,那么后面有三个自然数a、b和c,表示把公园a到公园b路径上所有的公园(包括a和b)的评价都修改为c。(c的绝对值不超过10000)
第二行有n个自然数,表示一开始小白对每个公园的评价(评价值的绝对值不超过10000)
下面有n-1行,每行两个数a和b,表示公园a和公园b直接由道路相连
再下面一行有一个自然数,表示m
最后m行,每行第一个数k表示要执行的操作。如果k为1,那么后面有两个自然数a和b,表示询问公园a到公园b路径上(包含a和b)最大的连续公园评价和(如果这条路径上每个公园的评价都为负数,那么最大连续和为0)。如果k为2,那么后面有三个自然数a、b和c,表示把公园a到公园b路径上所有的公园(包括a和b)的评价都修改为c。(c的绝对值不超过10000)
Output
对于每次询问,输出最大连续和。
Sample Input
5
-3 -2 1 2 3
1 2
2 3
1 4
4 5
3
1 2 5
2 3 4 2
1 2 5
Sample Output
5 9
Hint
对于30%的数据:n,m <= 100
对于70%的数据:n,m <= 50000
对于100%的数据:n,m <= 100000
对于70%的数据:n,m <= 50000
对于100%的数据:n,m <= 100000
Solution
做了线性公园(普通版)之后就来做一下。。。
什么都没想,直接上了最无脑的LCT。。。
对于每一个询问,MakeRoot之后Access,在当前Splay根节点的maxx就是答案了。
我们在更新打标记的时候,要在原有的树上打。。。(不能一直找左儿子)。。。
估计多数人都是写的树剖。
标记的维护见其他人的维护数列(太懒了)
什么都没想,直接上了最无脑的LCT。。。
对于每一个询问,MakeRoot之后Access,在当前Splay根节点的maxx就是答案了。
我们在更新打标记的时候,要在原有的树上打。。。(不能一直找左儿子)。。。
估计多数人都是写的树剖。
标记的维护见其他人的维护数列
CODE
#include<iostream>#include<cstring>#include<cstdio>using namespace std;inline int read(){char c;int rec=0,f=1;while((c=getchar())<'0'||c>'9')if(c=='-')f=-1;while(c>='0'&&c<='9')rec=rec*10+c-'0',c=getchar();return rec*f;}int n,m;struct LCT_Tree{int F,s[2],val,size;int sum,maxx,pmax[2];int C,R;inline void NewNode(int fa,int x){F=fa;C=R=0;size=1;val=sum=maxx=pmax[0]=pmax[1]=x;return ;}}tree[100005];inline bool Isroot(int v){return tree[tree[v].F].s[0]!=v&&tree[tree[v].F].s[1]!=v;}inline void PMAX(int v,int f){tree[v].pmax[f]=max(tree[tree[v].s[f]].pmax[f], tree[tree[v].s[f]].sum+tree[v].val+max(0,tree[tree[v].s[!f]].pmax[f]));}inline void Up(int v){tree[v].size=tree[tree[v].s[0]].size+1+tree[tree[v].s[1]].size;tree[v].sum=tree[tree[v].s[0]].sum+tree[v].val+tree[tree[v].s[1]].sum;tree[v].maxx=max(max(tree[tree[v].s[0]].maxx,tree[tree[v].s[1]].maxx), max(0,tree[tree[v].s[0]].pmax[1])+tree[v].val+max(0,tree[tree[v].s[1]].pmax[0]));PMAX(v,0);PMAX(v,1);return ;}inline void Same(int v,int x){if(v==0)return ;tree[v].C=1;tree[v].val=x;tree[v].sum=x*tree[v].size;tree[v].maxx=tree[v].pmax[0]=tree[v].pmax[1]=max(x,tree[v].sum);return ;}inline void Rev(int v){if(v==0)return ;tree[v].R^=1;swap(tree[v].s[0],tree[v].s[1]);swap(tree[v].pmax[0],tree[v].pmax[1]);return ;}inline void Down(int v){if(tree[v].C){Same(tree[v].s[0],tree[v].val);Same(tree[v].s[1],tree[v].val);tree[v].C=0;}if(tree[v].R){Rev(tree[v].s[0]);Rev(tree[v].s[1]);tree[v].R=0;}return ;}inline void Lazy(int v){if(!Isroot(v))Lazy(tree[v].F);Down(v);return ;}inline void Rot(int v){ int p=tree[v].F,g=tree[p].F; int t1=v==tree[p].s[1],t2=p==tree[g].s[1]; int ch=tree[v].s[1^t1]; if(!Isroot(p))tree[g].s[t2]=v;tree[ch].F=p; tree[v].F=g;tree[v].s[1^t1]=p; tree[p].F=v;tree[p].s[t1]=ch; Up(p);return;}inline void Splay(int v){Lazy(v); while(!Isroot(v)){ int p=tree[v].F,g=tree[p].F; if(!Isroot(p))(v==tree[p].s[1])^(p==tree[g].s[0])?Rot(v):Rot(p); Rot(v); }Up(v);return;}inline void Access(int v){for(int temp=0;v;temp=v,v=tree[v].F){Splay(v);tree[v].s[1]=temp;Up(v);}return ;}inline void Make_Root(int v){Access(v);Splay(v);Rev(v);return ;}inline void Link(int v1,int v2){Make_Root(v1);tree[v1].F=v2;return ;}inline int Find_Root(int v){while(!Isroot(v))v=tree[v].F;return v;}inline void Change(int v1,int v2,int x){Make_Root(v1);Access(v2);Same(Find_Root(v2),x);return ;}inline void Ask(int v1,int v2){Make_Root(v1);Access(v2);Splay(v2);cout<<tree[v2].maxx<<' ';return ;}int main(){n=read();for(int i=1;i<=n;i++)tree[i].NewNode(0,read());for(int i=1;i<n;i++)Link(read(),read());m=read();int x,y,z;for(int i=1;i<=m;i++){int f=read();if(f==1)Ask(read(),read());else {x=read();y=read();z=read();Change(x,y,z);}}cout<<'\n';return 0;}
0 0
- 小白逛公园加强版(vijos1620)
- 小白逛公园(vijos1083)
- 小白逛公园
- 小白逛公园
- 小白逛公园
- tyvj 1427 小白逛公园 (线段树)
- 【Vijos1083】小白逛公园(线段树)
- tyvj 1427 小白逛公园
- 小白逛公园 --线段树
- 1756: Vijos1083 小白逛公园
- bzoj1756 Vijos1083 小白逛公园
- vijos-P1083 小白逛公园
- 【vijos1083】小白逛公园
- TYVJ 1427 小白逛公园
- TYVJ P1427 小白逛公园
- Tyvj P1427 小白逛公园
- NKOI 1316 小白逛公园
- bzoj1756: Vijos1083 小白逛公园
- 用Java读取Windows的Command指令
- Asp.Net WebForm vs MVC
- SDE10.1 无法连接的问题解决
- 装饰设计模式简析
- android UI小结(一)
- 小白逛公园加强版(vijos1620)
- Java其他API介绍
- 性能的一些基本概念和原则
- 设计模式(一):策略模式+简单工厂模式
- 自己写的一个启动JBoss服务器的bat批处理
- 结合File类浅析递归的使用
- android UI小结(二)
- 【转载】linux sort 命令详解
- 自动化测试之 数据驱动 和 关键字驱动