您的位置:首页 > 其它

bzoj 3351 Regions

2016-01-14 10:31 295 查看
莫队加疯狂离线。。。竟然跑了个第一23333

/**************************************************************
Problem: 3351
User: Clare
Language: C++
Result: Accepted
Time:11932 ms
Memory:30264 kb
****************************************************************/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;

#define N 200010

int n,q,R,DFS_tot,Unit;
int Num
,color
,l
,r
,num
,D_color
;
long long Nownum
,Ans
;
vector<int> p
;
struct Edge{
int next,to;
}edge
;
int head
,tot;
struct Que{
int c,id;
};
vector<Que> f1
,f2
;
struct Node{
int pos,l,r;
bool operator < (const Node &a) const{
if(l/Unit==a.l/Unit)return r<a.r;
else return l/Unit<a.l/Unit;
}
}A
;
int S_tot;
bool flag
,D_flag
;
queue<int> Q;

inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}

void Addedge(int u,int v)
{
tot++;edge[tot].next=head[u];edge[tot].to=v;head[u]=tot;
}

void DFS_Get_Range(int k)
{
l[k]=++DFS_tot;D_color[DFS_tot]=color[k];
for(int i=head[k];i;i=edge[i].next)
DFS_Get_Range(edge[i].to);
r[k]=DFS_tot;
}

void Work1(int k)
{
memset(num,0,sizeof(num));
num[1]=(color[1]==k)?1:0;
Q.push(1);
while(!Q.empty())
{
int now=Q.front();Q.pop();
for(int i=head[now];i;i=edge[i].next)
{
int v=edge[i].to;
Nownum[color[v]]+=num[now];
num[v]=num[now]+((color[v]==k)?1:0);
Q.push(v);
}
}
}

void Work2()
{
memset(Nownum,0,sizeof(Nownum));
int L=0,R=0;
for(int i=1;i<=S_tot;i++)
{
while(R<A[i].r) {R++;Nownum[D_color[R]]++;}
while(R>A[i].r) {Nownum[D_color[R]]--;R--;}
while(L<A[i].l) {Nownum[D_color[L]]--;L++;}
while(L>A[i].l) {L--;Nownum[D_color[L]]++;}
int Now_color=color[A[i].pos];
for(int j=0;j<f2[Now_color].size();j++)
Ans[f2[Now_color][j].id]+=Nownum[f2[Now_color][j].c];
}
}

int main()
{
n=read();R=read();q=read();
Unit=(int)sqrt(n);
Num[color[1]=read()]++;p[color[1]].push_back(1);
for(int i=2;i<=n;i++)
{
int x=read();color[i]=read();
Num[color[i]]++;p[color[i]].push_back(i);
Addedge(x,i);
}
DFS_Get_Range(1);
for(int i=1;i<=q;i++)
{
int r1=read(),r2=read();
if(Num[r1]>Unit)
{
f1[r1].push_back((Que){r2,i});
D_flag[r1]=true;
}
else
{
f2[r1].push_back((Que){r2,i});
if(!flag[r1])
{
flag[r1]=true;
for(int j=0;j<p[r1].size();j++)
A[++S_tot].pos=p[r1][j],A[S_tot].l=l[A[S_tot].pos],A[S_tot].r=r[A[S_tot].pos];
}
}
}
for(int i=1;i<=R;i++)
{
if(D_flag[i])
{
memset(Nownum,0,sizeof(Nownum));
Work1(i);
for(int j=0;j<f1[i].size();j++)
Ans[f1[i][j].id]=Nownum[f1[i][j].c];
}
}
sort(A+1,A+S_tot+1);
Work2();
for(int i=1;i<=q;i++)
printf("%lld\n",Ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: