# bzoj4034 线段树+dfs序

https://www.lydsy.com/JudgeOnline/problem.php?id=4034

dfs序真是一个奥妙重重的东西

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
inline int read(){int now=0;register char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*10+c-'0',c=getchar());return now;}
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-9;
const int maxn = 4e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int N,M,K;
LL val[maxn];
struct Edge{
int to,next;
}edge[maxn * 2];
PII Index[maxn * 2];
PII pos[maxn];
int id = 0;
void dfs(int t,int fa){
Index[++id].fi = t;
Index[id].se = 1;
pos[t].fi = id;
for(int i = head[t]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v == fa) continue;
dfs(v,t);
}
Index[++id].fi = t;
Index[id].se = -1;
pos[t].se = id;
}
struct Tree{
int l,r;
int up,down;
LL sum,lazy;
}tree[maxn << 2];
void Pushup(int t){
tree[t].sum = tree[t << 1].sum + tree[t << 1 | 1].sum;
}
void Build(int t,int l,int r){
tree[t].l = l; tree[t].r = r;
tree[t].up = tree[t].down = tree[t].lazy = 0;
if(l == r){
if(Index[l].se == 1){
tree[t].sum = val[Index[l].fi];
tree[t].up++;
}else{
tree[t].sum = -val[Index[l].fi];
tree[t].down++;
}
return ;
}
int m = (l + r) >> 1;
Build(t << 1,l,m); Build(t << 1 | 1,m + 1,r);
Pushup(t);
tree[t].up = tree[t << 1].up + tree[t << 1 | 1].up;
tree[t].down = tree[t << 1].down + tree[t << 1 | 1].down;
}
void Pushdown(int t){
if(tree[t].lazy){
tree[t << 1].sum += (tree[t << 1].up - tree[t << 1].down) * tree[t].lazy;
tree[t << 1 | 1].sum += (tree[t << 1 | 1].up - tree[t << 1 | 1].down) * tree[t].lazy;
tree[t << 1].lazy += tree[t].lazy; tree[t << 1 | 1].lazy += tree[t].lazy;
tree[t].lazy = 0;
}
}
void update(int t,int l,int r,LL a){
if(l <= tree[t].l && tree[t].r <= r){
tree[t].sum += (tree[t].up - tree[t].down) * a;
tree[t].lazy += a;
return;
}
Pushdown(t);
int m = (tree[t].l + tree[t].r) >> 1;
if(r <= m) update(t << 1,l,r,a);
else if(l > m) update(t << 1 | 1,l,r,a);
else{
update(t << 1,l,m,a);
update(t << 1 | 1,m + 1,r,a);
}
Pushup(t);
}
LL query(int t,int l,int r){
if(l > r) return 0;
if(l <= tree[t].l && tree[t].r <= r){
return tree[t].sum;
}
Pushdown(t);
int m = (tree[t].l + tree[t].r) >> 1;
if(r <= m) return query(t << 1,l,r);
else if(l > m) return query(t << 1 | 1,l,r);
else{
return query(t << 1,l,m) + query(t << 1 | 1,m + 1,r);
}
}
int main()
{
Sca2(N,M); init();
For(i,1,N) Scl(val[i]);
int root = 1; id = 0;
dfs(root,-1);
Build(1,1,2 * N);
while(M--){
if(op == 1){
int x; Sca(x); LL a; Scl(a);
update(1,pos[x].fi,pos[x].fi,a); update(1,pos[x].se,pos[x].se,a);
}else if(op == 2){
int x; Sca(x); LL a; Scl(a);
update(1,pos[x].fi,pos[x].se,a);
}else{
int x; Sca(x);
Prl(query(1,1,pos[x].fi));
}
}
#ifdef VSCode
system("pause");
#endif
return 0;
}

posted @ 2018-10-24 13:11  Hugh_Locke  阅读(223)  评论(0编辑  收藏  举报