51nod 1782 Christmas tree dsu on tree+splay

Keywords: less

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;
}

Posted by eliezer on Wed, 06 Feb 2019 13:27:16 -0800