meaning of the title
Ze gets a Christmas tree, and he needs to hang gifts on it.
Zeta will perform m operations beforehand, each time hanging a[i] gift of type b[i] on each point of a chain (u[i],v[i]).
The k-aesthetics of a point is calculated by sorting all kinds of gifts at this point from small to large, and if the number is the same, from small to large.
Its k-beauty is the xor value of the first k kinds of gifts after ordering (if there are less than k kinds of gifts, put all kinds of gifts xor at this point).
Next, Q questions are given. Given w[i],k[i], the k[i] - aesthetic degree of point w[i] is calculated.
1≤n,Q,m,a[i],b[i],k[i]≤100000,1≤u[i],v[i],w[i]≤n
Analysis
The modification operation on the chain can be changed from a difference on the tree to a point modification operation.
You can use a splay to maintain the size order of each color, and then use dsu on tree to optimize it.
At first, I wanted to make a segment tree, looked at it and found that there was not enough space, then I gave up.
The psychopath wants to stay calm.
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
using namespace std;
typedef long long LL;
typedef pair<int,int> pi;
const int N=100005;
const int inf=100000;
int n,m,q,fa[N],dep[N],top[N],size[N],root,cnt,last[N],son[N],ans[N],c[N],stack[15];
LL sum[N];
struct edge{int to,next;}e[N*2];
struct tree{int w,s,l,r,fa;}t[N];
vector<pi> vec[N],que[N];
int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void pri(int x)
{
if (!x) {puts("0");return;}
int t=0;
while (x) stack[++t]=x%10,x/=10;
while (t) putchar(stack[t--]+'0');
puts("");
}
void addedge(int u,int v)
{
e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;
e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;
}
void dfs1(int x)
{
dep[x]=dep[fa[x]]+1;size[x]=!size[x]?1:vec[x].size();
for (int i=last[x];i;i=e[i].next)
{
if (e[i].to==fa[x]) continue;
fa[e[i].to]=x;
dfs1(e[i].to);
size[x]+=size[e[i].to];
}
}
void dfs2(int x,int chain)
{
top[x]=chain;son[x]=0;
for (int i=last[x];i;i=e[i].next)
if (e[i].to!=fa[x]&&size[e[i].to]>size[son[x]]) son[x]=e[i].to;
if (!son[x]) return;
dfs2(son[x],chain);
for (int i=last[x];i;i=e[i].next)
if (e[i].to!=fa[x]&&e[i].to!=son[x]) dfs2(e[i].to,e[i].to);
}
int get_lca(int x,int y)
{
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
inline void updata(int x)
{
t[x].w=t[t[x].l].w^t[t[x].r].w^x;
t[x].s=t[t[x].l].s+t[t[x].r].s+1;
}
inline void rttl(int x)
{
int y=t[x].r,p=t[x].fa;t[x].r=t[y].l;
t[t[y].l].fa=x;
root=x==root?y:root;
if (x==t[p].l) t[p].l=y;
else if (x==t[p].r) t[p].r=y;
t[y].fa=p;
t[y].l=x;t[x].fa=y;
updata(x);updata(y);
}
inline void rttr(int x)
{
int y=t[x].l,p=t[x].fa;t[x].l=t[y].r;
t[t[y].r].fa=x;
root=x==root?y:root;
if (x==t[p].l) t[p].l=y;
else if (x==t[p].r) t[p].r=y;
t[y].fa=p;
t[y].r=x;t[x].fa=y;
updata(x);updata(y);
}
void splay(int x,int y)
{
while (t[x].fa!=y)
{
int p=t[x].fa,g=t[p].fa;
if (g==y)
{
if (x==t[p].l) rttr(p);
else rttl(p);
return;
}
if (x==t[p].l)
if (p==t[g].l) rttr(g),rttr(p);
else rttr(p),rttl(g);
else
if (p==t[g].r) rttl(g),rttl(p);
else rttl(p),rttr(g);
}
}
inline bool cmp(int x,int y)
{
return sum[x]<sum[y]||sum[x]==sum[y]&&x<y;
}
inline void ins(int d)
{
int x=root,y;
while (x)
if (cmp(d,x)) y=x,x=t[x].l;
else y=x,x=t[x].r;
if (cmp(d,y)) t[y].l=d;
else t[y].r=d;
t[d].fa=y;splay(d,0);
}
inline void del(int d)
{
splay(d,0);
int nx=t[d].r,ls=t[d].l;
while (t[nx].l) nx=t[nx].l;
while (t[ls].r) ls=t[ls].r;
splay(nx,0);
if (!ls) t[nx].l=t[d].fa=0,updata(nx);
else splay(ls,nx),t[ls].r=t[d].fa=0,rttr(nx);
}
int query(int k)
{
int x=root,y;k=min(k+1,t[x].s);
while (x)
if (t[t[x].l].s+1==k) break;
else if (t[t[x].l].s+1>k) x=t[x].l;
else k-=t[t[x].l].s+1,x=t[x].r;
splay(x,0);
return t[t[x].l].w;
}
void work(int x,int op)
{
int w=c[x];
for (int i=0;i<vec[w].size();i++)
{
int p=vec[w][i].first,q=vec[w][i].second;
if (sum[q]) del(q);
sum[q]+=p*op;
if (sum[q]) ins(q);
}
}
void solve(int x)
{
for (int i=last[x];i;i=e[i].next)
if (e[i].to!=fa[x]&&e[i].to!=son[x]) solve(e[i].to),work(e[i].to,-1);
if (son[x]) solve(son[x]);
for (int i=last[x];i;i=e[i].next)
if (e[i].to!=fa[x]&&e[i].to!=son[x]) work(e[i].to,1);
work(x,1);
for (int i=0;i<que[x].size();i++) ans[que[x][i].second]=query(que[x][i].first);
for (int i=last[x];i;i=e[i].next)
{
if (e[i].to==fa[x]) continue;
if (vec[c[x]].size()<vec[c[e[i].to]].size()) swap(c[x],c[e[i].to]);
for (int j=0;j<vec[c[e[i].to]].size();j++) vec[c[x]].pb(vec[c[e[i].to]][j]);
vec[c[e[i].to]].clear();
}
}
int main()
{
n=read();
for (int i=1;i<n;i++)
{
int x=read(),y=read();
addedge(x,y);
}
dfs1(1);dfs2(1,1);
m=read();
for (int i=1;i<=m;i++)
{
int x=read(),y=read(),a=read(),b=read(),lca=get_lca(x,y);
vec[x].pb(mp(a,b));vec[y].pb(mp(a,b));vec[lca].pb(mp(-a,b));
if (fa[lca]) vec[fa[lca]].pb(mp(-a,b));
}
dfs1(1);dfs2(1,1);
q=read();
for (int i=1;i<=q;i++)
{
int x=read(),y=read();
que[x].pb(mp(y,i));
}
root=inf+1;sum[root]=(LL)inf*inf;
for (int i=1;i<=n;i++) c[i]=i;
solve(1);
for (int i=1;i<=q;i++) pri(ans[i]);
return 0;
}