Submission #415309

#TimeUsernameProblemLanguageResultExecution timeMemory
415309CSQ31Tropical Garden (IOI11_garden)C++14
69 / 100
358 ms67420 KiB
#include "garden.h"
#include <bits/stdc++.h>
#include "gardenlib.h"
using namespace std;
#define sz(a) (int)(a.size())
#define pb push_back
#define se second
typedef vector<vector<int>> vii;
typedef pair<int,int> pii;
const int MAXN = 4e5+5;
int nxt[MAXN][31];
vector<vector<pii>> g1(MAXN);
vii g2(MAXN);
void count_routes(int n, int m, int p, int r[][2], int q, int g[])
{
	for(int i=0;i<m;i++){
		g1[r[i][0]].pb({i,r[i][1]});
		g1[r[i][1]].pb({i,r[i][0]});
	}
	for(int i=0;i<n;i++)sort(g1[i].begin(),g1[i].end());
	for(int i=0;i<n;i++){
		int to = g1[i][0].se;
		if(g1[to][0].se != i){
			nxt[i][0] = to; //not beautiful
			g2[to].pb(i);
		}
		else {
			nxt[i][0] = to+n;
			g2[to+n].pb(i);
		}
		
		to = (sz(g1[i]) > 1)?g1[i][1].se:g1[i][0].se;
		if(g1[to][0].se != i){
			nxt[i+n][0] = to; //not beautiful
			g2[to].pb(i+n);
		}
		else {
			nxt[i+n][0] = to+n;
			g2[to+n].pb(i+n);
		}
	}
	for(int k=1;k<31;k++){
		for(int i=0;i<2*n;i++){
			nxt[i][k] = nxt[nxt[i][k-1]][k-1];
		}
		
	}	
	if(q == 1){
	  for(int i=0; i<q; i++) { 
		  int ans = 0;
		  for(int x=0;x<n;x++){
			  int cur = x;
			  int cnt = g[i];
			  for(int j=30;j>=0;j--){
				  if(cnt >= (1<<j)){
					  cur = nxt[cur][j];
					  cnt-=(1<<j);
				  }
			  }
			  if(cur == p || cur == p+n)ans++;
			  
		  } 
		  answer(ans);
	  }
	  return ;
	}
	vector<int>cycle(2*n),vis(2*n);
	int i = 0;
	while(!vis[i]){
		vis[i] = 1;
		i = nxt[i][0];
	}
	int len = 1;
	while(!cycle[i]){
		cycle[i] = len;
		len++;
		i = nxt[i][0];
	}
	len--;
	vector<int>comp(2*n); //which tree do you belong in?
	vector<int>dist(2*n); //distance from tree root
	for(int i=0;i<2*n;i++){
		if(cycle[i]){
			queue<int>qq;
			qq.push(i);
			while(!qq.empty()){
				int v = qq.front();
				qq.pop();
				comp[v] = i;
				for(int x:g2[v]){
					if(!cycle[x]){
						dist[x] = dist[v]+1;
						qq.push(x);
					}
				}
			}
		}
	}
	vii d(2,vector<int>(2*n,2e9));
	queue<int>qq;
	qq.push(p);
	d[0][p] = 0;
	vis.assign(2*n,0);
	vis[p] = 1;
	while(!qq.empty()){
		int v = qq.front();
		qq.pop();
		for(int x:g2[v]){
			if(vis[x])continue;
			vis[x] =1;
			d[0][x] = d[0][v]+1;
			qq.push(x);
		}
	}
	d[1][p+n] = 0;
	qq.push(p+n);
	vis.assign(2*n,0);
	vis[p+n] = 1;
	while(!qq.empty()){
		int v = qq.front();
		qq.pop();
		for(int x:g2[v]){
			if(vis[x])continue;
			vis[x] =1;
			d[1][x] = d[1][v]+1;
			qq.push(x);
		}
	}
	for(int i=0;i<q;i++){
		int ans = 0;
		for(int j=0;j<n;j++){
			bool ok = 0;
			if(!cycle[p]){
				if(d[0][j] == g[i])ok = 1;
			}else{
				int l1 = cycle[p] - cycle[comp[j]]; //their distance in the cycle
				int l2 = len-l1;
				int d = dist[j];
				if(g[i] >= d+l1 && (g[i]-d-l1)%len == 0)ok = 1;
				if(g[i] >= d+l2 && (g[i]-d-l2)%len == 0)ok = 1;
			}
			if(!cycle[p+n]){
				if(d[1][j] == g[i])ok = 1;
			}
			else{
				int l1 = cycle[p+n] - cycle[comp[j]]; //their distance in the cycle
				int l2 = len-l1;
				int d = dist[j];
				if(g[i] >= d+l1 && (g[i]-d-l1)%len == 0)ok = 1;
				if(g[i] >= d+l2 && (g[i]-d-l2)%len == 0)ok = 1;
				
			}
			
			ans+=ok;
		}
		answer(ans);
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...