RE的惨惨的(应该是答案错误导致解密出错吧)
查看原帖
RE的惨惨的(应该是答案错误导致解密出错吧)
164883
Zigh_Wang楼主2022/6/6 19:25

就,死的挺惨的,下了第一个点一直还是没有de出来,球球各位大佬帮帮忙吧,谢谢您们了orzzzzzzzzzzzzzzz

代码里注释的是我曾经出的种种奇怪的错(哽咽

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 1e5 + 5;

int inpt()
{
	int x = 0, f = 1;
	char ch;
	for(ch = getchar(); (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
	if(ch == '-'){
		f = -1;
		ch = getchar();
	}
	do{
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar();
	}while(ch >= '0' && ch <= '9');
	return x * f;
}

int n, m;
int val[MAXN];

int hd[MAXN], nxt[MAXN << 1], to[MAXN << 1], w[MAXN << 1], tot = 0;
void Add(int x, int y, int z)
{
	nxt[++tot] = hd[x];
	hd[x] = tot;
	to[tot] = y;
	w[tot] = z;
}

int ST[MAXN << 2][21], cnt = 0, first_ap[MAXN];
int dpt[MAXN], dis[MAXN];
void GetST0(int x, int fa, int dist)
{
	dpt[x] = dpt[fa] + 1;
	ST[++cnt][0] = x;//向后走1位表示自己(相当于实际上是向后走了2^i-1位) 
	first_ap[x] = cnt;
	dis[x] = dist;
//	if(x == 70448){
//		int chao = 0;
//	} 
	for(int i = hd[x]; i; i = nxt[i]){
		int y = to[i];
		if(y == fa) continue;
		GetST0(y, x, dist + w[i]);
		ST[++cnt][0] = x;
	}
}
bool cmp(int x, int y)
{
	return dpt[x] < dpt[y];
}
int lg[MAXN << 2];
void GetSTOthers()
{
	for(int i = 1; i <= cnt; i++){
		lg[i] = 31 - __builtin_clz(i);
	}
	for(int j = 1; j <= lg[cnt]; j++){
		for(int i = 1; i <= cnt - (1 << j); i++){
			ST[i][j] = min(ST[i][j - 1], ST[i + (1 << (j - 1))][j - 1], cmp);
		}
	}
}
int GetDis(int x, int y)
{
	if(first_ap[x] > first_ap[y]){
		swap(x, y);
	}
	int posx = first_ap[x], posy = first_ap[y];
	int len = posy - posx + 1;
	int lca = min(ST[posx][lg[len]], ST[posy - (1 << lg[len]) + 1][lg[len]], cmp);
	return dis[x] + dis[y] - 2 * dis[lca];
}

int rt = 0, MaxSon[MAXN];
int vis[MAXN];
int siz[MAXN], sz[MAXN];
void GetRoot(int x, int fa, int Total)
{
	MaxSon[x] = 0;
	siz[x] = 1;
	for(int i = hd[x]; i; i = nxt[i]){
		int y = to[i];
		if(y == fa || vis[y]) continue;
		GetRoot(y, x, Total);
		siz[x] += siz[y];
		MaxSon[x] = max(MaxSon[x], siz[y]);
	}
	MaxSon[x] = max(MaxSon[x], Total - siz[x]);
	if(MaxSon[x] < MaxSon[rt]){
		rt = x;
	}
}

vector<int> c[2][MAXN];
int pa[MAXN];
void BuildNewTree(int x, int Total)
{
	vis[x] = 1;
	sz[x] = Total + 1;
	c[0][x].resize(sz[x] + 1);
	c[1][x].resize(sz[x] + 1);
	for(int i = hd[x]; i; i = nxt[i]){
		int y = to[i];
		if(vis[y]) continue;
		rt = 0;
		int ls = siz[y];
		GetRoot(y, 0, siz[y]);
		pa[rt] = x;
		BuildNewTree(rt, ls);
	}
}

void Change(int opt, int pos, int x, int v)
{
	x++;//因为是以距离为下标,所以可能存在0,故加一排除这种情况 
	for(; x <= sz[pos]; x += (x & (-x))) c[opt][pos][x] += v;
}
int Ask(int opt, int pos, int x)
{
	x++;//因为是以距离为下标,所以可能存在0,故加一排除这种情况 
	int val = 0;
	x = min(x, sz[pos]);/*?????*/
	for(; x; x -= (x & (-x))) val += c[opt][pos][x];
	return val;
}
void Update(int x, int v)
{
	for(int i = x; i; i = pa[i]) Change(0, i, GetDis(x, i), v);
	for(int i = x; pa[i]; i = pa[i]) Change(1, i, GetDis(x, pa[i]), v);
}

int ans = 0;

int main()
{
//	freopen("P6329_1.in", "r", stdin);
//	freopen("my.out", "w", stdout);
	
	n = inpt(), m = inpt();
	for(int i = 1; i <= n; i++){
		val[i] = inpt();
	}
	for(int i = 1; i < n; i++){
		int x = inpt(), y = inpt();
		Add(x, y, 1);
		Add(y, x, 1);
	}
	
	GetST0(1, 0, 0);
	GetSTOthers();
	
	rt = 0;
	MaxSon[0] = n;
	GetRoot(1, 0, n);
	
	BuildNewTree(rt, n);
	
//	for(int i = 1; i <= n; i++){
//		printf("%d\n", pa[i]);
//	}
//	return 0;
	
	for(int i = 1; i <= n; i++){
		Update(i, val[i]);
	}
	for(int i = 1; i <= m; i++){
		int opt = inpt();
		if(!opt){
			int x = inpt() ^ ans, k = inpt() ^ ans;
			ans = 0;
			ans += Ask(0, x, k);
			for(int j = x; pa[j]; j = pa[j]){
				int d = GetDis(x, pa[j]);
				if(k < d) break;
				ans += Ask(0, pa[j], k - d) - Ask(1, j, k - d);//注意后面的那个是i!!!!!! 
			}
			printf("%d\n", ans);
		}else{
			int x = inpt() ^ ans, y = inpt() ^ ans;
//			ans = 0;
			Update(x, y - val[x]);
			val[x] = y;
		}
	}
	
	return 0;
} 
2022/6/6 19:25
加载中...