답안 #431786

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
431786 2021-06-17T15:27:27 Z Kerim Regions (IOI09_regions) C++17
100 / 100
4264 ms 102188 KB
#include "bits/stdc++.h"
#define MAXN 200009
#define INF 1000000007
#define mp(x,y) make_pair(x,y)
#define all(v) v.begin(),v.end()
#define pb(x) push_back(x)
#define wr cout<<"----------------"<<endl;
#define ppb() pop_back()
#define tr(ii,c) for(__typeof((c).begin()) ii=(c).begin();ii!=(c).end();ii++)
#define ff first
#define ss second
#define my_little_dodge 46
#define debug(x)  cerr<< #x <<" = "<< x<<endl;
using namespace std;
 
typedef long long ll;
typedef pair<int,int> PII;
template<class T>bool umin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
template<class T>bool umax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
const int C=25009;
const int K=400;
const int N=2e5+5;
int id[MAXN],idx,a[MAXN];
vector<int>adj[MAXN];
vector<PII>comp[MAXN];
int who[MAXN],mx[MAXN],who_color[MAXN];
int cnt[MAXN],sub[MAXN];
int bs[N/K+3][C];
int sb[C][N/K+3];
int tin[MAXN],tout[MAXN],T;
void pre(int nd=1){
	tin[nd]=++T;
	sub[nd]=1;
	for(auto to:adj[nd]){
		pre(to);
		sub[nd]+=sub[to];
		if(umax(mx[nd],sub[to]))
			who[nd]=to;
	}
	tout[nd]=T;
	
}
//bb, bs
void dfs0(int color_id,int nd=1,int cnt_black=0){
	bs[color_id][a[nd]]+=cnt_black;
	cnt_black+=(~id[a[nd]] and id[a[nd]]==color_id);
	for(auto to:adj[nd])
		dfs0(color_id,to,cnt_black);
}
//sb
void add(int nd){
	cnt[a[nd]]++;
	for(auto to:adj[nd])
		add(to);
}
void rem(int nd){
	cnt[a[nd]]--;
	for(auto to:adj[nd])
		rem(to);
}
void dfs1(int nd=1,int keep=1){
	for(auto to:adj[nd])	
		if(to!=who[nd])
			dfs1(to,0);
	if(who[nd])
		dfs1(who[nd],1);
	for(auto to:adj[nd])	
		if(to!=who[nd])
			add(to);
	cnt[a[nd]]++;
	//here you have all color's cnt of my subtree
	for(int c=0;c<idx;c++)
		sb[a[nd]][c]+=cnt[who_color[c]];
	if(!keep)
		rem(nd);
}
int ata(int x,int y){
	return (tin[x]<=tin[y] and tout[y]<=tout[x]);
}
bool is_heavy(int x){
	return (int(comp[x].size())>K);
}
//log(S_i<K)~=8
int get(int x,PII tmp){
	int a=lower_bound(all(comp[x]),mp(tmp.ff,-1))-comp[x].begin();
	int b=upper_bound(all(comp[x]),mp(tmp.ss,INF))-comp[x].begin();
	return b-a;
}
map<PII,int>cache;
int main(){
    //~ freopen("file.in", "r", stdin);
    int n,c,q;
    scanf("%d%d%d",&n,&c,&q);
    scanf("%d",&a[1]);
    for(int i=2;i<=n;i++){
		int p;
		scanf("%d%d",&p,&a[i]);
		adj[p].pb(i);
	}
	pre();
	for(int i=1;i<=n;i++)
		comp[a[i]].pb(mp(tin[i],tout[i]));
	idx=0;
	for(int i=1;i<=c;i++){
		sort(all(comp[i]));
		if(is_heavy(i)){
			who_color[idx]=i;
			id[i]=idx++;
		}
		else
			id[i]=-1;		
	}
	for(int i=0;i<idx;i++)
		dfs0(i);
	dfs1();
	int res;
	while(q--){
		int a,b;
		scanf("%d%d",&a,&b);
		if(cache.find(mp(a,b))==cache.end()){
			if(~id[a])res = bs[id[a]][b];
			else if(~id[b])res = sb[a][id[b]];
			else{
				//ss
				res=0;
				for(int i=0;i<int(comp[a].size());i++)
					res+=get(b,comp[a][i]);
			}
			cache[mp(a,b)]=res;
		}
		printf("%d\n",cache[mp(a,b)]);
		fflush(stdout);
	}
	return 0;
}

Compilation message

regions.cpp: In function 'int main()':
regions.cpp:93:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   93 |     scanf("%d%d%d",&n,&c,&q);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~
regions.cpp:94:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   94 |     scanf("%d",&a[1]);
      |     ~~~~~^~~~~~~~~~~~
regions.cpp:97:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   97 |   scanf("%d%d",&p,&a[i]);
      |   ~~~~~^~~~~~~~~~~~~~~~~
regions.cpp:119:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  119 |   scanf("%d%d",&a,&b);
      |   ~~~~~^~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 9672 KB Output is correct
2 Correct 6 ms 9672 KB Output is correct
3 Correct 7 ms 9736 KB Output is correct
4 Correct 8 ms 9736 KB Output is correct
5 Correct 13 ms 9792 KB Output is correct
6 Correct 26 ms 9892 KB Output is correct
7 Correct 36 ms 9884 KB Output is correct
8 Correct 39 ms 10048 KB Output is correct
9 Correct 54 ms 10820 KB Output is correct
10 Correct 89 ms 10844 KB Output is correct
11 Correct 136 ms 11200 KB Output is correct
12 Correct 155 ms 12308 KB Output is correct
13 Correct 208 ms 11696 KB Output is correct
14 Correct 227 ms 12460 KB Output is correct
15 Correct 318 ms 17100 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1040 ms 18172 KB Output is correct
2 Correct 1359 ms 16488 KB Output is correct
3 Correct 2221 ms 23412 KB Output is correct
4 Correct 303 ms 13296 KB Output is correct
5 Correct 351 ms 16624 KB Output is correct
6 Correct 701 ms 31116 KB Output is correct
7 Correct 915 ms 36624 KB Output is correct
8 Correct 1022 ms 51028 KB Output is correct
9 Correct 2348 ms 29720 KB Output is correct
10 Correct 2462 ms 98612 KB Output is correct
11 Correct 4264 ms 32880 KB Output is correct
12 Correct 1424 ms 58904 KB Output is correct
13 Correct 1996 ms 62004 KB Output is correct
14 Correct 2459 ms 71844 KB Output is correct
15 Correct 3367 ms 90676 KB Output is correct
16 Correct 3297 ms 102188 KB Output is correct
17 Correct 3050 ms 90752 KB Output is correct