求求大佬教萌新优化常数,死活过不去
查看原帖
求求大佬教萌新优化常数,死活过不去
248872
y_dove楼主2020/5/18 00:24
/*震波*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn = 2e5 + 10;
int n,m;
inline int gc() {
    static char buf[1000000], *p1 = buf, *p2 = buf;
    return (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2)) ? EOF : *p1++;
    //return getchar();
}
inline int read(){
	char ch = gc();	
	int x = 0;
	while(ch < '0' || ch > '9')			ch = gc();
	while(ch >= '0' && ch <= '9')		x = x * 10 + ch - 48,ch = gc();
	return x;
}
inline void write(int x){
	if(!x)	return;
	write(x/10);
	putchar(x%10+'0');
}
struct Edge{
	int next,point;
}edge[maxn*2];
int head[maxn];
int dsiz[maxn];
int tot = 0;
inline void add(int x,int y){
	edge[++tot].next = head[x];
	edge[tot].point = y;
	head[x] = tot;
}
int maxp[maxn];
int siz[maxn];
int vis[maxn];
int f[maxn];
int in[maxn];
int a[maxn];
int rt = 0;
int dep[maxn];
void getrt(int x,int fa,int sum){
	siz[x] = 1;		maxp[x] = 0;
	for(register int i = head[x]; i ; i = edge[i].next){
		int y = edge[i].point;
		if(y == fa || vis[y])		continue;
		getrt(y,x,sum);
		siz[x] += siz[y];
		maxp[x] = max(maxp[x],siz[y]);
	}
	maxp[x] = max(maxp[x],sum - siz[x]);
	if(maxp[rt] > maxp[x])		rt = x;
}
#define T 20
inline int Min(int x,int y){
	if(dep[x] < dep[y])		return x;
	return y;
}
int g[maxn*2][21],intot;
void Dfs(int x,int fa){
	g[++intot][0] = x;
	in[x] = intot;
	for(register int i = head[x]; i ; i = edge[i].next){
		int y = edge[i].point;
		if(y == fa)		continue;
		dep[y] = dep[x] + 1; 
		Dfs(y,x);
		g[++intot][0] = x;
	}
}
int lg2[maxn];
void rmq(){
	lg2[1] = 0;
	for(int i = 2; i <= intot; ++i)		lg2[i] = lg2[i >> 1] + 1;
	int t = lg2[intot];
	for(register int j = 1; j <= t; ++j)
		for(register int i = 1; i <= intot - (1 << j) + 1; ++i)
			g[i][j] = Min(g[i][j-1],g[i+(1<<(j-1))][j-1]);
}
inline int lca(int l,int r){
	l = in[l],r = in[r];
	if(l > r)		swap(l,r);
	int t = lg2[r-l+1];
	return Min(g[l][t],g[r-(1<<t)+1][t]);
}
inline int Dis(int x,int y){
	return dep[x] + dep[y] - 2 * dep[lca(x,y)];
}
void build(int u,int sum){
	vis[u] = 1;		dsiz[u] = sum;
	for(register int i = head[u]; i ; i = edge[i].next){
		int v = edge[i].point;
		if(vis[v])		continue;
		int nowsum = (siz[v] > siz[u]) ? sum - siz[u] : siz[v];
		maxp[rt = 0] = 1e9;
		getrt(v,0,nowsum);
		f[rt] = u;
		build(rt,nowsum);
	}
}
struct SegmentTree{
	int lc[maxn*32],rc[maxn*32],dat[maxn*32];
	int root[maxn]; 
	int cnt;
	void Insert(int &p,int l,int r,int pos,int v){
		if(!p)	p = ++cnt;
		dat[p] += v;
		if(l == r)	return;
		int mid = (l + r) >> 1;
		if(pos <= mid)		Insert(lc[p],l,mid,pos,v);
		else	Insert(rc[p],mid+1,r,pos,v);
	}
	int ask(int p,int l,int r,int a,int b){
		if(a > b)	return 0;
		if(a <= l && b >= r)		return dat[p];
		int mid = (l + r) >> 1;
		int ans = 0;
		if(a <= mid)
			ans += ask(lc[p],l,mid,a,b);
		if(b > mid)
			ans += ask(rc[p],mid+1,r,a,b);
		return ans;
	}
}t1,t2;
inline void Modify(int x,int v){
	int idx = x;
	while(x){
		t1.Insert(t1.root[x],0,dsiz[x],Dis(idx,x),v);
		if(f[x])	t2.Insert(t2.root[x],0,dsiz[x],Dis(idx,f[x]),v);
		x = f[x];
	}
}
inline int query(int x,int k){
	int idx = x;
	int lst = 0;
	int ans = 0;
	while(x){
		int d = Dis(x,idx);
		if(k - d < 0){
			lst = x;
			x = f[x];
			continue;
		}
		ans += t1.ask(t1.root[x],0,dsiz[x],0,k-d);
		if(lst)		ans -= t2.ask(t2.root[lst],0,dsiz[lst],0,k-d);
		lst = x;
		x = f[x];
	}
	return ans;
}
void pre(){
	build(rt,n);
	for(register int i = 1; i <= n; ++i)		Modify(i,a[i]);
} 
int main()
{
	n = read(),m = read();
	for(int i = 1; i <= n; ++i)
		a[i] = read();
	for(int i = 1; i < n; ++i){
		int x = read(),y = read();
		add(x,y);		add(y,x);
	}
	maxp[rt = 0] = 1e9;
	getrt(1,0,n) ;
	dep[rt] = 1;
	Dfs(rt,0);
	rmq();
	pre();
	int ans = 0;
	for(int i = 1; i <= m; ++i){
		int op = read();
		if(op){
			int x = read(),v = read();
			x ^= ans,v ^= ans;
			Modify(x,v-a[x]);
			a[x] = v; 
		}
		else{
			int x = read(),k = read();
			x ^= ans,k ^= ans;
			ans = query(x,k);
			if(!ans)	putchar('0');
			else
				write(ans);
			putchar('\n');
		}
	}
	return 0;
}

2020/5/18 00:24
加载中...