求条,悬棺
查看原帖
求条,悬棺
812227
Sunrise_beforeglow楼主2025/1/17 22:29
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,q,cnt,sl[400005],sr[400005],sum[400005],lazy[400005],tot=1;
int f[200005],last[200005];
vector<int>v[200005];
map<int,int>mp;
int t=0;
set<int>s[200005];
void dfs(int x,int fa)
{
    f[x]=++cnt;
    for(int i=0;i<v[x].size();i++)
    {
        if(v[x][i]!=fa)dfs(v[x][i],x);
    }
    last[f[x]]=cnt;
}
void push_up(int x){sum[x]=sum[sl[x]]+sum[sr[x]];}
void push_down(int x,int l,int r)
{
    int mid=(l+r)/2;
    lazy[sl[x]]+=lazy[x];
    lazy[sr[x]]+=lazy[x];
    sum[sl[x]]+=lazy[x]*(mid-l+1);
    sum[sr[x]]+=lazy[x]*(r-mid);
    lazy[x]=0;
}
void build(int x,int l,int r)
{
    if(l==r)return;
    int mid=(l+r)/2;
    sl[x]=++tot;
    sr[x]=++tot;
    build(sl[x],l,mid);
    build(sr[x],mid+1,r);
}
void gai(int x,int l,int r,int ql,int qr,int zhi)
{
    if(l==ql&&r==qr)
    {
        lazy[x]+=zhi;
        sum[x]+=zhi*(r-l+1);
        return;
    }
    int mid=(l+r)/2;
    push_down(x,l,r);
    if(qr<=mid)gai(sl[x],l,mid,ql,qr,zhi);
    else if(mid<ql)gai(sr[x],mid+1,r,ql,qr,zhi);
    else 
    {
        gai(sl[x],l,mid,ql,mid,zhi);
        gai(sr[x],mid+1,r,mid+1,qr,zhi);
    }
    push_up(x);
}
int query(int x,int l,int r,int ql,int qr)
{
    if(l==ql&&r==qr)return sum[x];
    push_down(x,l,r);
    int mid=(l+r)/2;
    if(qr<=mid)return query(sl[x],l,mid,ql,qr);
    else if(mid<ql)return query(sr[x],mid+1,r,ql,qr);
    else 
    {
        return query(sl[x],l,mid,ql,mid)+query(sr[x],mid+1,r,mid+1,qr);
    }
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>q;
    for(int i=1;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    dfs(1,0);
    build(1,1,n);
    while(q--)
    {
        int op,x,y;
        cin>>op;
        if(op==1)
        {
            cin>>x>>y;
            x=f[x];
            if(!mp.count(y))mp[y]=++t;
            y=mp[y];
            gai(1,1,n,x,last[x],1);
            auto l=s[y].lower_bound(x);
            auto r=(s[y].upper_bound(last[x]));
            auto sx=l;
            auto nxt=l;
            for(l;l!=r;l++)gai(1,1,n,*l,last[*l],-1);
            for(sx;sx!=r;sx=nxt)
            {
                sx++;
                nxt=sx;
                sx--;
                s[y].erase(sx);
            }
            s[y].insert(x);
        }
        else
        {
            cin>>x;
            x=f[x];
            cout<<query(1,1,n,x,last[x])<<'\n';
        }
    }
    return 0;
}
2025/1/17 22:29
加载中...