【Codeforces696E】...Wait for it...

来源:互联网 发布:java easyui 编辑:程序博客网 时间:2024/05/18 02:25

一个一个删,树剖线段树上维护即可。

#include <bits/stdc++.h>#define gc getchar()#define ll long long#define mid (l+r>>1)#define inf (ll)2e18#define N 100009#define root 1,1,n#define lc cur<<1#define rc lc|1#define lson lc,l,mid#define rson rc,mid+1,r#define now cur,l,rusing namespace std;ll n,m,Q,first[N],number,fa[N],size[N],top[N],deep[N],Mson[N],dfn[N],id[N],ed[N],cnt;ll tg[N<<2],print[N],pos[N];struct edge{    ll to,next;    void add(ll x,ll y)    {        to=y,next=first[x],first[x]=number;    }}e[N<<1];struct node{    ll pos,val,id;    node(ll pos=0,ll val=0,ll id=0):pos(pos),val(val),id(id){}    bool operator <(const node &rhs) const    {        return val<rhs.val||(val==rhs.val&&pos<rhs.pos);    }}Min[N<<2];vector<node> a[N];ll read(){    ll x=1;    char ch;    while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;    ll s=ch-'0';    while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';    return s*x;}void dfs1(ll x){    deep[x]=deep[fa[x]]+1;    size[x]=1;    for (ll i=first[x];i;i=e[i].next)        if (e[i].to!=fa[x])        {            fa[e[i].to]=x;            dfs1(e[i].to);            size[x]+=size[e[i].to];            if (size[e[i].to]>size[Mson[x]]) Mson[x]=e[i].to;        }}void dfs2(ll x,ll y){    top[x]=y;    id[dfn[x]=++cnt]=x;    if (Mson[x]) dfs2(Mson[x],y);    for (ll i=first[x];i;i=e[i].next)        if (e[i].to!=fa[x]&&e[i].to!=Mson[x]) dfs2(e[i].to,e[i].to);    ed[x]=cnt;}void down(ll cur,ll l,ll r){    if (tg[cur]>0)    {        tg[lc]+=tg[cur];        tg[rc]+=tg[cur];        Min[lc].val+=tg[cur];        Min[rc].val+=tg[cur];        tg[cur]=0;    }}void up(ll cur,ll l,ll r){    Min[cur]=min(Min[lc],Min[rc]);}void build(ll cur,ll l,ll r){    tg[cur]=0;    if (l==r)    {        Min[cur]=(a[id[l]].size()!=0?a[id[l]][0]:node(0,inf,inf));        return;    }    build(lson);    build(rson);    up(now);}void ins(ll cur,ll l,ll r,ll L,ll R,ll x){    if (L<=l&&R>=r)    {        tg[cur]+=x;        Min[cur].val+=x;        return;    }    down(now);    if (L<=mid) ins(lson,L,R,x);    if (R>mid) ins(rson,L,R,x);    up(now);}ll get_tg(ll cur,ll l,ll r,ll x){    if (l==r) return tg[cur];    if (x<=mid) return tg[cur]+get_tg(lson,x);    else return tg[cur]+get_tg(rson,x);}void del(ll cur,ll l,ll r,ll x){    if (l==r)    {        pos[id[l]]++;        Min[cur]=(a[id[l]].size()>pos[id[l]]?a[id[l]][pos[id[l]]]:node(0,inf,inf));        if (a[id[l]].size()>pos[id[l]]) Min[cur].val+=get_tg(root,l);        return;    }    down(now);    if (x<=mid) del(lson,x);    else del(rson,x);    up(now);}node qry(ll cur,ll l,ll r,ll L,ll R){    if (L<=l&&R>=r) return Min[cur];    down(now);    node ret=node(0,inf,inf);    if (L<=mid) ret=min(ret,qry(lson,L,R));    if (R>mid) ret=min(ret,qry(rson,L,R));    return ret;}node qry(ll x,ll y){    node ret=node(0,inf,inf);    for (;top[x]!=top[y];x=fa[top[x]])    {        if (deep[top[x]]<deep[top[y]]) swap(x,y);        ret=min(ret,qry(root,dfn[top[x]],dfn[x]));    }    if (dfn[x]>dfn[y]) swap(x,y);    return min(ret,qry(root,dfn[x],dfn[y]));}int main(){    n=read(),m=read(),Q=read();    //n=1,m=100000,Q=100000;    for (ll i=1;i<n;i++)    {        ll x=read(),y=read();        e[++number].add(x,y),e[++number].add(y,x);    }    for (ll i=1;i<=m;i++)    {        ll x=read();        //ll x=1;        a[x].push_back(node(x,i,i));    }    for (ll i=1;i<=n;i++) pos[i]=0,sort(a[i].begin(),a[i].end());    dfs1(1);    dfs2(1,1);    build(root);    while (Q--)    {        ll op=read();        //ll op=1;        if (op==1)        {            ll x=read(),y=read(),k=read(),num=0;            //ll x=1,y=1,k=1,num=0;            for (num=0;num<k;num++)            {                node Now=qry(x,y);                if (Now.pos==0) break;                else                {                    print[num+1]=Now.id;                    del(root,dfn[Now.pos]);                }            }            printf("%lld",num);            for (ll i=1;i<=num;i++) printf(" %lld",print[i]);            puts("");        }        else        {            ll x=read(),k=read();            ins(root,dfn[x],ed[x],k);        }    }    return 0;}