萌新惨死于洛谷树下。。
  • 板块P3401 洛谷树
  • 楼主pikabi
  • 当前回复6
  • 已保存回复6
  • 发布时间2020/9/11 20:07
  • 上次更新2023/11/5 13:24:42
查看原帖
萌新惨死于洛谷树下。。
209604
pikabi楼主2020/9/11 20:07

用的是树剖和线段树,存储异或前缀和,每次操作修改子树,但是 WA 到 pts.

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cctype>
#define ll long long
#define inf 1023456789

using namespace std;

inline int read(){
	int x=0,w=0;char ch=getchar();
	while (!isdigit(ch))w|=ch=='-',ch=getchar();
	while (isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return w?-x:x;
}

struct node{
	int to, nxt, val;
}e[1000005];

int n, q, head[100005], cnt;

inline void add(int from, int to, int val){
	e[++cnt].nxt = head[from];
	head[from] = cnt;
	e[cnt].to = to;
	e[cnt].val = val;
}

int f[100005], dep[100005], son[100005], siz[100005], vv[100005], two[15];

inline void dfs1(int p, int fa, int w){
	vv[p] = w;
	f[p] = fa;
	dep[p] = dep[fa] + 1;
	siz[p] = 1;
	for(int i = head[p]; i; i = e[i].nxt ){
		if(e[i].to == fa) continue;
		dfs1(e[i].to , p, e[i].val ^ w);
		siz[p] += siz[e[i].to ];
		if(siz[son[p]] < siz[e[i].to ]) son[p] = e[i].to ; 
	}
}

int id[100005], top[100005], tot, vvv[100005];

inline void dfs2(int p, int topf){
	top[p] = topf;
	id[p] = ++tot;
	vvv[tot] = vv[p];
	if(!son[p]) return ;
	dfs2(son[p] , topf); 
	for(int i = head[p]; i; i = e[i].nxt ){
		if(e[i].to == f[p] || e[i].to == son[p]) continue ;
		dfs2(e[i].to ,e[i].to );
	}
}

struct Segment_Tree{
	int val[12];
	int tag;
}a[5000005]; 

inline int ls(int p){
	return p << 1;
} 

inline int rs(int p){
	return p << 1 | 1;
}

inline void update(int p){
	for(int i = 0; i <= 10; i++)
	a[p].val[i] = a[ls(p)].val[i] + a[rs(p)].val[i];
}

inline void push_up(int p, int l, int r, int k){
	a[p].tag ^= k;
	int now = 0;
	while(k){
		if(k & 1) a[p].val[now] = r - l + 1 - a[p].val[now];
		now ++;
		k >>= 1;
	}
}

inline void push_down(int p, int l, int r){
	if(!a[p].tag ) return ;
	int mid = l + r >> 1;
	push_up(ls(p), l, mid, a[p].tag );
	push_up(rs(p), mid + 1, r, a[p].tag );
	a[p].tag = 0;
}

inline void build(int p, int l, int r){
	if(l == r){
		int now = 0, w = vvv[l];
		while(w){
			a[p].val[now] = w & 1;
			w >>= 1;
			now++;
		}
		return ;
	}
	int mid = l + r >> 1;
	build(ls(p), l, mid);
	build(rs(p), mid + 1, r);
	update(p);
}

int ans[12];

inline void modify(int p, int l, int r, int L, int R, int k){
	if(L <= l && r <= R){
		int now = 0, w = k;
		while(w){
			if(w & 1)
			a[p].val[now] = r - l + 1 - a[p].val[now] ;
			w >>= 1;
			now++;
		}
		a[p].tag ^= k;
		return ;
	}
	push_down(p, l, r);
	int mid = l + r >> 1;
	if(L <= mid) modify(ls(p), l, mid, L, R, k);
	if(mid < R) modify(rs(p), mid + 1, r, L, R, k);
	update(p);
}

inline void query(int p, int l, int r, int L, int R){
	if(L <= l && r <= R){
		for(int i = 0; i <= 10; i++)
		ans[i] += a[p].val[i];
		return ;
	}
	push_down(p, l, r);
	int mid = l + r >> 1;
	if(L <= mid) query(ls(p), l, mid, L, R);
	if(mid < R) query(rs(p), mid + 1, r, L, R); 
	update(p);
}

inline ll query_range(int u, int v){
	int sum = dep[u] + dep[v];
	for(int i = 0; i <= 10; i++) ans[i] = 0;
	while(top[u] != top[v]){
		if(dep[top[u]] < dep[top[v]]) swap(u, v);
		query(1, 1, n, id[top[u]], id[u]);
		u = f[top[u]];
	}
	if(dep[u] < dep[v]) swap(u, v);
	query(1, 1, n, id[v], id[u]);
	sum += - 2 * dep[v] + 1;
	ll res = 0;
	for(int i = 0; i <= 10; i++){
		res += (ll) two[i] * ans[i] * (sum - ans[i]);
	}
	return res;
}

inline void up_son(int p, int k){
	modify(1, 1, n, id[p], id[p] + siz[p] - 1, k);
}

int main(){
	n = read(), q = read();
	two[0] = 1;
	for(int i = 1; i <= 10; i++) two[i] = two[i - 1] * 2;
	for(int i = 1; i < n; i++){
		int x = read(), y = read(), z = read();
		add(x, y, z);
		add(y, x, z);
	}
	dfs1(1, 0, 0);
	dfs2(1, 1);
	build(1, 1, n);
	for(int i = 1; i <= q; i++){
		int opt = read();
		if(opt == 1){
			int u = read(), v = read();
			printf("%lld\n",query_range(u, v));
		}
		else {
			int u = read(), v = read(), w = read();
			int ww = w;
			if(f[u] == v){
				w ^= vvv[u];
				vvv[u] = ww;
				up_son(u, w);
			}
			else {
				w ^= vvv[v];
				vvv[v] = ww;
				up_son(v, w);
			}
		}
	}
}
2020/9/11 20:07
加载中...