Submission #114256

# Submission time Handle Problem Language Result Execution time Memory
114256 2019-05-31T15:22:48 Z gs14004 Space Pirate (JOI14_space_pirate) C++17
47 / 100
2000 ms 46852 KB
#include <bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef pair<int, int> pi;
const int mod = 1e9 + 7;
const int MAXN = 100005;

lint k;
int n, a[MAXN];
int par[60][MAXN];
lint ans[17][MAXN];
int cmp[MAXN];

lint anc(int x, lint k){
	for(int i=0; k; i++){
		if(k & 1){
			x = par[i][x];
		}
		k >>= 1;
	}
	return x;
}

void add_path(int x, int c){
	for(int i=0; c; i++){
		if(c & 1){
			ans[i][x]++;
			x = par[i][x];
		}
		c >>= 1;
	}
}

vector<int> gph[MAXN];
int lvl[MAXN], dep[MAXN];
int num[MAXN];

void dfs(int x){
	for(auto &i : gph[x]){
		lvl[i] = max(lvl[i], lvl[x]);
		dep[i] = dep[x] + 1;
		dfs(i);
	}
}

namespace Case1{
	vector<int> tr[MAXN];
	int dep[MAXN];
	bool inCyc[MAXN];
	void add_edge(int s, int e){
		tr[s].push_back(e);
	}
	void dfs(int x){
		for(auto &i : tr[x]){
			dep[i] = dep[x] + 1;
			dfs(i);
		}
	}
	int dfs2(int pos, int startDep, int endDep){
		int ret = 0;
		if(dep[pos] < endDep && dep[pos] >= startDep) ret++;
		for(auto &i : tr[pos]) ret += dfs2(i, startDep, endDep);
		if(dep[pos] == startDep) ans[0][pos] += ret;
		return ret;
	}
	int dfs3(int pos, int startDep, int endDep){
		int ret = 0;
		if(dep[pos] < endDep && dep[pos] >= startDep) ret++;
		for(auto &i : tr[pos]){
			if(!inCyc[i]){
				ret += dfs3(i, startDep, endDep);
			}
		}
		if(dep[pos] == startDep) ans[0][pos] += ret;
		return ret;
	}
	void solve(vector<int> cyc, lint k){
		for(auto &i : cyc) inCyc[i] = 1;
		for(int i=0; i+1<cyc.size(); i++){
			tr[cyc[i+1]].push_back(cyc[i]);
		}
		dfs(cyc.back());
		// beautiful case
		for(int i = 2; i<=cyc.size(); i++){
			int original_pinpoint = k % i;
			dfs2(cyc.back(), i - k % i - 1, i - 1);
			ans[0][cyc[original_pinpoint]] += dfs2(cyc.back(), -1, i - k % i - 1);
		}
		// ugly case
		/*
		for(int i = cyc.size() + 1; i <= n; i++){
			int d = cyc.size() - i;
			for(int j = 0; j < cyc.size(); j++){
				int pos = max(i - 1 - k % i, 1ll * ((int)cyc.size() - 1 - j) + d);
				dfs3(cyc[j], pos, i - 1 - k % i + j);
				if(k % i < cyc.size()){
					ans[0][cyc[k % i]] += 
						dfs2(cyc[j], d, pos);
				}
			}
		}*/
	}
}

void dfsCyc(int x, vector<int> &cyc, lint k){
	{
		// TODO: quadratic
		for(int i=0; i<num[x]; i++){
			auto arrival = k;
			int cycLength = dep[x] + cyc.size() - (num[x] - i) + 1;
			if(cycLength <= cyc.size()) continue;
			arrival %= cycLength;
			if(arrival <= i){
				ans[0][cyc[arrival]]++;
			}
			else{
				arrival -= i + 1;
				ans[0][anc(x, arrival)]++;
			}
		}
		// TODO: quadratic
		for(int i=num[x]; i<cyc.size(); i++){
			auto arrival = k - i - 1;
			int cycLength = dep[x] + i - num[x] + 1;
			arrival %= cycLength;
			ans[0][anc(x, arrival)]++;
		}
	}
	for(auto &i : gph[x]){
		if(cmp[i] == 2) continue;
		Case1::add_edge(x, i);
		num[i] = num[x];
		dep[i] = dep[x] + 1;
		dfsCyc(i, cyc, k);
	}
}


void solve_cycle(vector<int> v, lint k){
	for(int i=0; i<v.size(); i++){
		num[v[i]] = i;
	}
	for(auto &i : v){
		dfsCyc(i, v, k);
	}
	Case1::solve(v, k);
}

void solve_path(vector<int> v){ // TODO: quadratic
	dep[v.back()] = 1;
	dfs(v.back());
	for(int i=1; i<=n; i++){
		if(!cmp[par[20][i]]) continue;
		int w = v.size() - lvl[i];
		int pos = anc(i, k - w);
		add_path(pos, w);
		for(int j = 1; j <= lvl[i]; j++){
			lint upV = k - (lvl[1] - j + 1);
			upV %= (dep[i] - j + 1);
			ans[0][anc(i, upV)]++;
		}
	}
}

int main(){
	scanf("%d %lld",&n,&k);
	for(int i=1; i<=n; i++){
		scanf("%d",&a[i]);
		gph[a[i]].push_back(i);
	}
	memcpy(par[0], a, sizeof(par[0]));
	for(int i=1; i<60; i++){
		for(int j=1; j<=n; j++){
			par[i][j] = par[i-1][par[i-1][j]];
		}
	}
	for(int i=1; cmp[i]<2; i=a[i]) cmp[i]++;
	int pthcnt = n - count(cmp + 1, cmp + n + 1, 0);
	int onecnt = count(cmp + 1, cmp + n + 1, 1);
	ans[0][anc(1, k)] += 1ll * n * (n - pthcnt);
	for(int i=1; i<=n; i++){
		if(!cmp[par[20][i]]){
			int pos = anc(i, k - pthcnt);
			add_path(pos, pthcnt);
		}
	}
	vector<int> pth;
	vector<int> cyc;
	for(int i=1; ; i=a[i]){
		if(cmp[i] == 1){
			lvl[i] = onecnt - pth.size();
			pth.push_back(i);
		}
		if(cmp[i] == 2){
			if(cyc.size() && i == cyc.front()) break;
			cyc.push_back(i);
		}
	}
	if(pth.size()) solve_path(pth);
	solve_cycle(cyc, k - pth.size());
	for(int i=16; i; i--){
		for(int j=1; j<=n; j++){
			ans[i - 1][par[i - 1][j]] += ans[i][j];
			ans[i - 1][j] += ans[i][j];
		}
	}
	for(int i=1; i<=n; i++) printf("%lld\n", ans[0][i]);
}

Compilation message

space_pirate.cpp: In function 'void Case1::solve(std::vector<int>, lint)':
space_pirate.cpp:79:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i=0; i+1<cyc.size(); i++){
                ~~~^~~~~~~~~~~
space_pirate.cpp:84:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i = 2; i<=cyc.size(); i++){
                  ~^~~~~~~~~~~~
space_pirate.cpp: In function 'void dfsCyc(int, std::vector<int>&, lint)':
space_pirate.cpp:111:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    if(cycLength <= cyc.size()) continue;
       ~~~~~~~~~~^~~~~~~~~~~~~
space_pirate.cpp:122:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i=num[x]; i<cyc.size(); i++){
                     ~^~~~~~~~~~~
space_pirate.cpp: In function 'void solve_cycle(std::vector<int>, lint)':
space_pirate.cpp:140:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0; i<v.size(); i++){
               ~^~~~~~~~~
space_pirate.cpp: In function 'int main()':
space_pirate.cpp:166:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d %lld",&n,&k);
  ~~~~~^~~~~~~~~~~~~~~~~
space_pirate.cpp:168:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d",&a[i]);
   ~~~~~^~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 7 ms 5888 KB Output is correct
2 Correct 6 ms 5888 KB Output is correct
3 Correct 6 ms 5888 KB Output is correct
4 Correct 7 ms 5888 KB Output is correct
5 Correct 7 ms 5888 KB Output is correct
6 Correct 6 ms 5888 KB Output is correct
7 Correct 6 ms 5888 KB Output is correct
8 Correct 6 ms 5888 KB Output is correct
9 Correct 6 ms 5888 KB Output is correct
10 Correct 7 ms 5760 KB Output is correct
11 Correct 6 ms 5760 KB Output is correct
12 Correct 7 ms 5888 KB Output is correct
13 Correct 7 ms 5888 KB Output is correct
14 Correct 6 ms 5888 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 7 ms 5888 KB Output is correct
2 Correct 6 ms 5888 KB Output is correct
3 Correct 6 ms 5888 KB Output is correct
4 Correct 7 ms 5888 KB Output is correct
5 Correct 7 ms 5888 KB Output is correct
6 Correct 6 ms 5888 KB Output is correct
7 Correct 6 ms 5888 KB Output is correct
8 Correct 6 ms 5888 KB Output is correct
9 Correct 6 ms 5888 KB Output is correct
10 Correct 7 ms 5760 KB Output is correct
11 Correct 6 ms 5760 KB Output is correct
12 Correct 7 ms 5888 KB Output is correct
13 Correct 7 ms 5888 KB Output is correct
14 Correct 6 ms 5888 KB Output is correct
15 Correct 14 ms 7132 KB Output is correct
16 Correct 9 ms 7040 KB Output is correct
17 Correct 21 ms 7168 KB Output is correct
18 Correct 545 ms 7388 KB Output is correct
19 Correct 123 ms 7200 KB Output is correct
20 Correct 284 ms 7332 KB Output is correct
21 Correct 342 ms 7416 KB Output is correct
22 Correct 109 ms 7288 KB Output is correct
23 Correct 276 ms 7416 KB Output is correct
24 Correct 66 ms 7288 KB Output is correct
25 Correct 9 ms 7040 KB Output is correct
26 Correct 477 ms 7424 KB Output is correct
27 Correct 80 ms 7160 KB Output is correct
28 Correct 106 ms 7132 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 585 ms 46852 KB Output is correct
2 Execution timed out 2064 ms 35060 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 7 ms 5888 KB Output is correct
2 Correct 6 ms 5888 KB Output is correct
3 Correct 6 ms 5888 KB Output is correct
4 Correct 7 ms 5888 KB Output is correct
5 Correct 7 ms 5888 KB Output is correct
6 Correct 6 ms 5888 KB Output is correct
7 Correct 6 ms 5888 KB Output is correct
8 Correct 6 ms 5888 KB Output is correct
9 Correct 6 ms 5888 KB Output is correct
10 Correct 7 ms 5760 KB Output is correct
11 Correct 6 ms 5760 KB Output is correct
12 Correct 7 ms 5888 KB Output is correct
13 Correct 7 ms 5888 KB Output is correct
14 Correct 6 ms 5888 KB Output is correct
15 Correct 14 ms 7132 KB Output is correct
16 Correct 9 ms 7040 KB Output is correct
17 Correct 21 ms 7168 KB Output is correct
18 Correct 545 ms 7388 KB Output is correct
19 Correct 123 ms 7200 KB Output is correct
20 Correct 284 ms 7332 KB Output is correct
21 Correct 342 ms 7416 KB Output is correct
22 Correct 109 ms 7288 KB Output is correct
23 Correct 276 ms 7416 KB Output is correct
24 Correct 66 ms 7288 KB Output is correct
25 Correct 9 ms 7040 KB Output is correct
26 Correct 477 ms 7424 KB Output is correct
27 Correct 80 ms 7160 KB Output is correct
28 Correct 106 ms 7132 KB Output is correct
29 Correct 585 ms 46852 KB Output is correct
30 Execution timed out 2064 ms 35060 KB Time limit exceeded
31 Halted 0 ms 0 KB -