线段树合并T成60求助

P3899 [湖南集训] 更为厉害

Danno0v0 @ 2022-10-21 09:18:40

#include<bits/stdc++.h>
#define ls(x) tree[x].l
#define rs(x) tree[x].r
#define Max 1000001
using namespace std;
struct node
{
    int tot,l,r;
}tree[1<<26];
struct q
{
    int id,k;
};
vector<q>ques[Max];
int cnt;
int fi[Max],nx[Max],to[Max],tot;
int depth[Max],size[Max];
int n,q,ans[Max];
int root[Max];
int link(int a,int b)
{
    nx[++tot]=fi[a];
    fi[a]=tot;
    to[tot]=b;
}
void update(int x)
{
    tree[x].tot=0;
    if(ls(x)) tree[x].tot+=tree[ls(x)].tot;
    if(rs(x)) tree[x].tot+=tree[rs(x)].tot;
}
void change(int x,int b,int k,int L,int R)
{
    if(L==R&&L==b)
    {
        tree[x].tot+=k;
        return; 
    }
    int M=(L+R)>>1;
    if(b<=M)
    {
        if(!ls(x)) ls(x)=++cnt;
        change(ls(x),b,k,L,M);
    }
    else
    {
        if(!rs(x)) rs(x)=++cnt;
        change(rs(x),b,k,M+1,R);
    }
    update(x);
}
int query(int x,int l,int r,int L,int R)
{
    if(l<=L&&R<=r)
        return tree[x].tot;
    int M=(L+R)>>1,ans=0;
    if(l<=M&&ls(x)) ans+=query(ls(x),l,r,L,M);
    if(M<R&&rs(x)) ans+=query(rs(x),l,r,M+1,R);
    return ans;
}
int Merge(int x,int y,int L,int R)
{
    if(!y) return x;
    if(!x) return y;
    if(L==R)
    {
        tree[x].tot+=tree[y].tot;
        return x;
    }
    int M=(L+R)>>1;
    ls(x)=Merge(ls(x),ls(y),L,M);
    rs(x)=Merge(rs(x),rs(y),M+1,R);
    update(x);
    return x;
}
void dfs(int x,int fath)
{
    root[x]=++cnt;
    size[x]=1;
    for(int i=fi[x];i;i=nx[i])
    {
        int v=to[i];
        if(v!=fath)
            depth[v]=depth[x]+1,dfs(v,x),size[x]+=size[v],root[x]=Merge(root[x],root[v],1,n);
    }
    for(int i=0;i<ques[x].size();i++)
    {
        int id=ques[x][i].id,k=ques[x][i].k;
        ans[id]+=min(k,depth[x]-1)*(size[x]-1)+query(root[x],depth[x]+1,depth[x]+k,1,n);
    }
    change(root[x],depth[x],size[x]-1,1,n);
}
int main()
{
    int x,y;
    cin>>n>>q;
    for(int i=1;i<n;i++)
        cin>>x>>y,link(x,y),link(y,x);
    for(int i=1;i<=q;i++)
        cin>>x>>y,ques[x].push_back({i,y});
    depth[1]=1;
    dfs(1,0);
    for(int i=1;i<=q;i++)
        cout<<ans[i]<<endl;
}

by Danno0v0 @ 2022-10-21 09:53:30

破案了,query小R写成大R了……

这都能有60建议加强


by jijidawang @ 2022-10-21 10:48:37

@Danno0v0 这个要卡是不是就是链状物了


|