记录编号 451944 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [IOI 2009]区域发展 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 8.970 s
提交时间 2017-09-18 17:41:30 内存使用 106.20 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
const int N=2e5+10,M=25010;
int n,m,q,c[N],w[N],head[N],next[N];
void add(int f,int t){
    static int cnt=0;
    w[++cnt]=t;
    next[cnt]=head[f];
    head[f]=cnt;
}
int size[M],ans1[510][M],ans2[510][M];
int id[M],ID,*ans,flag;
vector<int> L[N],R[N];
void dfs(int x){
    size[c[x]]++;
    static int cnt=0;
    L[c[x]].push_back(++cnt);
    for (int i=head[x];i;i=next[i]) dfs(w[i]);
    R[c[x]].push_back(cnt);
}
int query(int x,int y){
    int pp=0,pl=0,pr=0,ans=0,cnt=0;
    while (pp<size[y]||pl<size[x]||pr<size[x]){
        int vp=L[y][pp],vl=L[x][pl],vr=R[x][pr];
        if (vl<=vp&&vl<=vr) ans-=cnt,pl++;else
        if (vp<vl&&vp<=vr) cnt++,pp++;else
        if (vr<vl&&vr<vp) ans+=cnt,pr++;
    }
    return ans;
}
void dfs1(int x){//求r1=x的答案
    static int cnt=0;
    if (c[x]==flag) cnt++;else ans[c[x]]+=cnt;
    for (int i=head[x];i;i=next[i]) dfs1(w[i]);
    if (c[x]==flag) cnt--;
}
int cnt[N];
void dfs2(int x){//求r2=x的答案
    cnt[x]=0;
    for (int i=head[x];i;i=next[i]) dfs2(w[i]),cnt[x]+=cnt[w[i]];
    if (c[x]==flag) cnt[x]++;else ans[c[x]]+=cnt[x];
}
int main()
{
    freopen("region.in","r",stdin);
    freopen("region.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&q,&c[1]);
    for (int i=2;i<=n;i++){
        int x;
        scanf("%d%d",&x,&c[i]);
        add(x,i);
    }
    dfs(1);
    for (int i=1;i<=m;i++){
        L[i].push_back(1e9);
        R[i].push_back(1e9);
    }
    int block_size=sqrt(n);
    for (int i=1;i<=m;i++)
    if (size[i]>block_size){
        id[i]=++ID;flag=i;
        ans=ans1[ID];dfs1(1);
        ans=ans2[ID];dfs2(1);
    }
    while (q--){
        int x,y,ans=0;
        scanf("%d%d",&x,&y);
        if (size[x]>block_size) ans=ans1[id[x]][y];else
        if (size[y]>block_size) ans=ans2[id[y]][x];else
            ans=query(x,y);
        printf("%d\n",ans);
    }
    return 0;
}