求助

P3899 [湖南集训] 更为厉害

FlappyBear @ 2019-01-09 21:36:02

为什么自己写的和标程100000级别对拍一晚上没错,交上来却爆0/:v:/

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
long long n,q,nex[650000],fir[650000],to[650000],tot,tot1,T[350000];
long long dep[350000],la_num[350000],st_num[350000],Max_dep,size[350000];
long long find_ans(long long last,long long pos,long long l,long long r,long long place);
void dfs2(long long x,long long fa);
long long update(long long last,long long l,long long r,long long place,long long w);
void Update(long long x);
long long build(long long l,long long r);
void dfs1(long long x,long long fa);
struct node{
    long long ls,rs;
    long long value;
}s[300300*20];
//此题按照dfn序为顺序建立主席树,查询答案时直接树相减即可 
int main()
{
    freopen("rand","r",stdin);
    freopen("0.pts","w",stdout);
    cin>>n>>q;
    for(long long i=1;i<n;i++)
    {
        long long u,v;
        scanf("%lld%lld",&u,&v);
        nex[++tot]=fir[u];fir[u]=tot;to[tot]=v;
        nex[++tot]=fir[v];fir[v]=tot;to[tot]=u;
    }
    dfs1(1,0);//处理size和dep 
    T[0]=build(1,Max_dep);
    dfs2(1,0);
    for(long long i=q;i;i--)
    {
        long long ans=0;
        long long x,k;
        scanf("%lld%lld",&x,&k);
        ans+=min(dep[x]-1,k)*(size[x]-1);
        if(st_num[x]<=la_num[x])
        ans+=find_ans(T[st_num[x]-1],T[la_num[x]],1,Max_dep,dep[x]+k);
        printf("%lld\n",ans);
    }
    return 0;
}
long long find_ans(long long last,long long pos,long long l,long long r,long long place)//No Problem
{
    if(l==r)
    return s[pos].value-s[last].value;
    long long mid=l+r>>1;
    if(place>mid)
    return find_ans(s[last].rs,s[pos].rs,mid+1,r,place)+s[s[pos].ls].value-s[s[last].ls].value;
    return find_ans(s[last].ls,s[pos].ls,l,mid,place);
}       
void dfs2(long long x,long long fa)//No Problem
{
    T[++tot1]=update(T[tot1-1],1,Max_dep,dep[x],size[x]-1);
    st_num[x]=tot1+1;//子树入边 
    for(long long e=fir[x];e;e=nex[e])
    {
        long long v=to[e];
        if(v==fa)
        continue;
        dfs2(v,x);
    }
    la_num[x]=tot1;//子树出边 
    return;
}
long long update(long long last,long long l,long long r,long long place,long long w)//No Problem
{
    long long pos=++tot;
    if(l==r)
    {
        s[pos].value=s[last].value+w;
        return pos;
    }
    s[pos].ls=s[last].ls;
    s[pos].rs=s[last].rs;
    long long mid=l+r>>1;
    if(place<=mid)
    s[pos].ls=update(s[last].ls,l,mid,place,w);
    else
    s[pos].rs=update(s[last].rs,mid+1,r,place,w);
    Update(pos);
    return pos;
}
void Update(long long x)//No Problem
{
    s[x].value=s[s[x].ls].value+s[s[x].rs].value;
    return;
}
long long build(long long l,long long r)//No Problem
{
    long long pos=++tot;
    if(l==r)
    return pos;
    long long mid=l+r>>1;
    s[pos].ls=build(l,mid);
    s[pos].rs=build(mid+1,r);
    return pos;
}
void dfs1(long long x,long long fa)//No Problem
{
    dep[x]=dep[fa]+1;
    Max_dep=max(Max_dep,dep[x]);
    size[x]=1;
    for(long long e=fir[x];e;e=nex[e])
    {
        long long v=to[e];
        if(v==fa)
        continue;
        dfs1(v,x);
        size[x]+=size[v];
    }
    return;
}

by FlappyBear @ 2019-01-09 21:37:00

删掉freopen也没有用/:v:/


|