SPOJ GSS7 Can you answer these queries VII

Can you answer these queries VII

Time Limit: 1000ms

Memory Limit: 262144KB

This problem will be judged on SPOJ. Original ID: GSS7
64-bit integer IO format: %lld      Java class name: Main

Given a tree with N ( N<=100000 ) nodes. Each node has a interger value x_i ( |x_i|<=10000 ).

You have to apply Q ( Q<=100000 ) operations:

1. 1 a b : answer the maximum contiguous sum (maybe empty,will always larger than or equal to 0 ) from the path a->b ( inclusive ).

2. 2 a b c : change all value in the path a->b ( inclusive ) to c.

Input

first line consists one interger N.

next line consists N interger x_i.

next N-1 line , each consists two interger u,v , means that node u and node v are connected

next line consists 1 interger Q.

next Q line : 1 a b or 2 a b c .

Output

For each query, output one line the maximum contiguous sum.

Example

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

Output:
5
9

Source

my own problems

解题:LCT

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 100010;
  4 struct arc{
  5     int to,next;
  6     arc(int x = 0,int y = -1){
  7         to = x;
  8         next  = y;
  9     }
 10 }e[maxn<<1];
 11 struct LCT{
 12     int fa[maxn],ch[maxn][2],sz[maxn],parent[maxn];
 13     int key[maxn],ls[maxn],rs[maxn],ms[maxn],sum[maxn];
 14     bool reset[maxn];
 15     inline void pushup(int x){
 16         sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]];
 17         sum[x] = key[x] + sum[ch[x][0]] + sum[ch[x][1]];
 18         ls[x] = max(ls[ch[x][0]],sum[ch[x][0]] + key[x] + ls[ch[x][1]]);
 19         rs[x] = max(rs[ch[x][1]],sum[ch[x][1]] + key[x] + rs[ch[x][0]]);
 20         ms[x] = max(ms[ch[x][0]],ms[ch[x][1]]);
 21         ms[x] = max(ms[x],key[x] + rs[ch[x][0]] + ls[ch[x][1]]);
 22     }
 23     inline void set(int x,int val){
 24         if(!x) return;
 25         reset[x] = true;
 26         key[x] = val;
 27         sum[x] = sz[x]*val;
 28         ls[x] = rs[x] = ms[x] = max(0,sum[x]);
 29     }
 30     inline void pushdown(int x){
 31         if(reset[x]){
 32             set(ch[x][0],key[x]);
 33             set(ch[x][1],key[x]);
 34             reset[x] = false;
 35         }
 36     }
 37     void rotate(int x,int kd){
 38         int y = fa[x];
 39         pushdown(y);
 40         pushdown(x);
 41         ch[y][kd^1] = ch[x][kd];
 42         fa[ch[x][kd]] = y;
 43         fa[x] = fa[y];
 44         ch[x][kd] = y;
 45         fa[y] = x;
 46         if(fa[x]) ch[fa[x]][y == ch[fa[x]][1]] = x;
 47         pushup(y);
 48     }
 49     void splay(int x,int goal = 0){
 50         pushdown(x);
 51         int y = x;
 52         while(fa[y]) y = fa[y];
 53         if(x != y){
 54             parent[x] = parent[y];
 55             parent[y] = 0;
 56             while(fa[x] != goal){
 57                 pushdown(fa[fa[x]]);
 58                 pushdown(fa[x]);
 59                 pushdown(x);
 60                 if(fa[fa[x]] == goal) rotate(x,x == ch[fa[x]][0]);
 61                 else{
 62                     int y = fa[x],z = fa[y],s = (ch[z][0] == y);
 63                     if(x == ch[y][s]){
 64                         rotate(x,s^1);
 65                         rotate(x,s);
 66                     }else{
 67                         rotate(y,s);
 68                         rotate(x,s);
 69                     }
 70                 }
 71             }
 72             pushup(x);
 73         }
 74     }
 75     void access(int x){
 76         for(int y = 0; x; x = parent[x]){
 77             splay(x);
 78             fa[ch[x][1]] = 0;
 79             parent[ch[x][1]] = x;
 80             ch[x][1] = y;
 81             fa[y] = x;
 82             parent[y] = 0;
 83             y = x;
 84             pushup(x);
 85         }
 86     }
 87     void update(int x,int y,int z){
 88         access(y);
 89         for(y = 0; x; x = parent[x]){
 90             splay(x);
 91             if(!parent[x]){
 92                 key[x] = z;
 93                 set(y,z);
 94                 set(ch[x][1],z);
 95                 return;
 96             }
 97             fa[ch[x][1]] = 0;
 98             parent[ch[x][1]] = x;
 99             ch[x][1] = y;
100             fa[y] = x;
101             parent[y] = 0;
102             y = x;
103             pushup(x);
104         }
105     }
106     int query(int x,int y){
107         access(y);
108         for(y = 0; x; x = parent[x]){
109             splay(x);
110             if(!parent[x]){
111                 int ret = max(ms[y],ms[ch[x][1]]);
112                 ret = max(ret,key[x] + ls[y] + ls[ch[x][1]]);
113                 return ret;
114             }
115             fa[ch[x][1]] = 0;
116             parent[ch[x][1]] = x;
117             ch[x][1] = y;
118             fa[y] = x;
119             parent[y] = 0;
120             y = x;
121             pushup(x);
122         }
123     }
124     void init(){
125         memset(fa,0,sizeof fa);
126         memset(parent,0,sizeof parent);
127         memset(reset,false,sizeof reset);
128         memset(ch,0,sizeof ch);
129         sz[0] = 0;
130     }
131 }lct;
132 int head[maxn],tot;
133 void add(int u,int v){
134     e[tot] = arc(v,head[u]);
135     head[u] = tot++;
136 }
137 void dfs(int u,int fa){
138     for(int i = head[u]; ~i; i = e[i].next){
139         if(e[i].to == fa) continue;
140         lct.parent[e[i].to] = u;
141         dfs(e[i].to,u);
142     }
143 }
144 int main(){
145     int n,m,u,v,x,y,z,op;
146     while(~scanf("%d",&n)){
147         memset(head,-1,sizeof head);
148         tot =  0;
149         lct.init();
150         for(int i = 1; i <= n; ++i){
151             lct.sz[i] = 1;
152             scanf("%d",&lct.key[i]);
153             lct.sum[i] = lct.key[i];
154             lct.ls[i] = lct.rs[i] = lct.ms[i] = max(0,lct.key[i]);
155         }
156         for(int i = 1; i < n; ++i){
157             scanf("%d%d",&u,&v);
158             add(u,v);
159             add(v,u);
160         }
161         dfs(1,1);
162         scanf("%d",&m);
163         while(m--){
164             scanf("%d%d%d",&op,&x,&y);
165             if(op == 1) printf("%d\n",lct.query(x,y));
166             else{
167                 scanf("%d\n",&z);
168                 lct.update(x,y,z);
169             }
170         }
171     }
172     return 0;
173 }

时间: 2024-08-10 23:12:31

SPOJ GSS7 Can you answer these queries VII的相关文章

SPOJ 6779 GSS7 - Can you answer these queries VII

题目描述 给定一棵树,有N(N≤100000)个节点,每一个节点都有一个权值xi xi?(∣xi∣≤10000) 你需要执行Q(Q≤100000)次操作: 1 a b 查询(a,b)这条链上的最大子段和,可以为空(即输出00) 2 a b c 将(a,b)这条链上的所有点权变为c (∣c∣<=10000) 输入格式: 第一行一个整数N 接下来一行有N个整数表示xi 接下来N−1行,每行两个整数u,v表示u和v之间有一条边相连 接下来一行一个整数QQ 之后有Q行,每行诸如1 a b或者2 a b

Spoj 6779 Can you answer these queries VII 树链剖分 在树上任意路径的最大子段和 区间修改点权

题目链接:点击打开链接 题意: rt.. 在询问时,两端向上爬时记录从深度浅的到深度深的方向上的 (也就是左最大连续子段和) 最后两个点在同一条重链上时合并. 合并时要注意有4种情况, 详见代码. 线段树部分和5相似. #include <cstdio> #include <iostream> #include <string.h> #include <vector> using namespace std; inline void rd(int &

SPOJ 1043 Can you answer these queries I 求任意区间最大连续子段和 线段树

题目链接:点击打开链接 维护区间左起连续的最大和,右起连续的和.. #include <cstdio> #include <iostream> #include <algorithm> #include <string.h> #include <math.h> #include <vector> #include <map> using namespace std; #define N 50050 #define Lson

SPOJ 4487. Can you answer these queries VI splay

题目链接:点击打开链接 题意比较明显,不赘述. 删除时可以把i-1转到根,把i+1转到根下 则i点就在 根右子树 的左子树,且只有i这一个 点 #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> using namespace std; #define N 300500 #define inf 10000000 #define L(x) tree[x].ch[

SPOJ GSS3 Can you answer these queries III (线段树)

题目大意: 求区间最大子区间的和. 思路分析: 记录左最大,右最大,区间最大. 注意Q_L  和 Q_R  就好. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define maxn 55555 using na

SPOJ GSS4 Can you answer these queries IV (线段树)

题目大意: 给出N个数 0     操作   把 l -----  r之间的数全部开平方 1     操作  输出 l -----r  之间的和 思路分析: 判断区间里的数字是否全相同.如果相同, 将cov 置为该数 查询的时候和更新的时候,如果碰到cov != -1 的  就直接返回就可以了 #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #incl

spoj gss2 : Can you answer these queries II 离线&amp;&amp;线段树

1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang Zhe cannot solve but get Wrong Answer from most of the OI problems. And he refuse to write two program of same kind at all. So he always failes in co

SPOJ GSS5 Can you answer these queries V (线段树)

原来有一两个人说我不帅的时候,我不以为意,逗我玩而已,后来几乎所有 人都说我不帅,我才真正意识到事态的严重,这社会骗子真是越来越多了... 好吧我承认,这个笑话不好笑,其实我想说的是,做人一定要坚持自己的原则, 哪怕有一天所有人都和你背道而驰,都不要放弃自己当初的梦想,如果有一天, 我们淹没在人海之中,庸碌一生,那是因为我们不够努力,不够勇敢的去面对生活. 每天积累一点点,嗯,满足简单的快乐. ---------------------------------------------------

bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树

2482: [Spoj1557] Can you answer these queries II Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 145  Solved: 76[Submit][Status][Discuss] Description 给定n个元素的序列. 给出m个询问:求l[i]~r[i]的最大子段和(可选空子段). 这个最大子段和有点特殊:一个数字在一段中出现了两次只算一次. 比如:1,2,3,2,2,2出现了3次,但只算一次,