Submission #151805

#TimeUsernameProblemLanguageResultExecution timeMemory
151805qkxwsm고대 책들 (IOI17_books)C++14
42 / 100
168 ms23500 KiB
/*
PROG: template
LANG: C++11
    _____
  .'     '.
 /  0   0  \
|     ^     |
|  \     /  |
 \  '---'  /
  '._____.'
 */
#include <bits/stdc++.h>
#include "books.h"

using namespace std;

template<class T>
void readi(T &x)
{
	T input = 0;
	bool negative = false;
	char c = ' ';
	while (c < '-')
	{
		c = getchar();
	}
	if (c == '-')
	{
		negative = true;
		c = getchar();
	}
	while (c >= '0')
	{
		input = input * 10 + (c - '0');
		c = getchar();
	}
	if (negative)
	{
		input = -input;
	}
	x = input;
}
template<class T>
void printi(T output)
{
	if (output == 0)
	{
		putchar('0');
		return;
	}
	if (output < 0)
	{
		putchar('-');
		output = -output;
	}
	int aout[20];
	int ilen = 0;
	while(output)
	{
		aout[ilen] = ((output % 10));
		output /= 10;
		ilen++;
	}
	for (int i = ilen - 1; i >= 0; i--)
	{
		putchar(aout[i] + '0');
	}
	return;
}
template<class T>
void ckmin(T &a, T b)
{
	a = min(a, b);
}
template<class T>
void ckmax(T &a, T b)
{
	a = max(a, b);
}
long long randomize(long long mod)
{
	return ((1ll << 30) * rand() + (1ll << 15) * rand() + rand()) % mod;
}

#define MP make_pair
#define PB push_back
#define PF push_front
#define LB lower_bound
#define UB upper_bound
#define fi first
#define se second

const long double PI = 4.0 * atan(1.0);
const long double EPS = 1e-20;

#define MAGIC 347
#define SINF 10007
#define CO 1000007
#define INF 1000000007
#define BIG 1000000931
#define LARGE 1696969696967ll
#define GIANT 2564008813937411ll
#define LLINF 2696969696969696969ll
#define MAXN 1013

long long normalize(long long x, long long mod = INF)
{
	return (((x % mod) + mod) % mod);
}

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

int N, S, K;
vector<int> arr;
bool vis[MAXN];
bool useless[MAXN];
vector<int> cyc[MAXN];
int id[MAXN];
int lt[MAXN], rt[MAXN];
ll ans = 0;
bool seen[MAXN][MAXN];
bool ex[MAXN][MAXN];
pii ext[MAXN][MAXN];
int dp[MAXN][MAXN];
int mintable[25][MAXN], maxtable[25][MAXN];
int lg2[MAXN];
vector<int> pts;

int query(int L, int R, bool flag)
{
	//query min
	//floor of log2?
	int SZ = R - L + 1, lg = lg2[SZ];
	if (flag)
	{
		return max(maxtable[lg][L], maxtable[lg][R - (1 << lg) + 1]);
	}
	return min(mintable[lg][L], mintable[lg][R - (1 << lg) + 1]);
}
pii extend(int L, int R)
{
	if (ex[L][R])
	{
		return ext[L][R];
	}
	ex[L][R] = true;
	int lo = L, hi = R;
	while(true)
	{
		int lt = query(lo, hi, 0), rt = query(lo, hi, 1);
		if (lt == lo && rt == hi)
		{
			break;
		}
		ckmin(lo, lt); ckmax(hi, rt);
	}
	ext[L][R] = MP(lo, hi);
	return ext[L][R];
}
int solve(int L, int R)
{
	if (seen[L][R])
	{
		return dp[L][R];
	}
	seen[L][R] = true;
	pii trans;
	if (L == 0)
	{
		if (R == N - 1)
		{
			dp[L][R] = 0;
		}
		else
		{
			trans = extend(L, R + 1);
			dp[L][R] = 2 + solve(trans.fi, trans.se);
		}
	}
	else
	{
		if (R == N - 1)
		{
			trans = extend(L - 1, R);
			dp[L][R] = 2 + solve(trans.fi, trans.se);
		}
		else
		{
			trans = extend(L - 1, R);
			dp[L][R] = 2 + solve(trans.fi, trans.se);
//			if (L == 420 && R == 428) cerr << trans.fi << ' ' << trans.se << ' ' << dp[L][R] << endl;
			trans = extend(L, R + 1);
			ckmin(dp[L][R], 2 + solve(trans.fi, trans.se));
//			if (L == 420 && R == 428) cerr << trans.fi << ' ' << trans.se << ' ' << dp[L][R] << endl;
		}
	}
	//	cerr << L << ' ' << R << ' ' << dp[L][R] << endl;
	return dp[L][R];
}
ll minimum_walk(vector<int> p, int s)
{
	s = p[s];
	for (int j = p.size() - 1; j > s; j--)
	{
		if (p[j] == j)
		{
			useless[j] = true;
		}
		else
		{
			break;
		}
	}
	for (int j = 0; j < s; j++)
	{
		if (p[j] == j)
		{
			useless[j] = true;
		}
		else
		{
			break;
		}
	}
	for (int j = 0; j < p.size(); j++)
	{
		if (!useless[j])
		{
			arr.PB(p[j]);
		}
	}
	if (arr.empty()) return 0;
	N = arr.size();
	int sm = INF;
	for (int i = 0; i < N; i++)
	{
		ckmin(sm, arr[i]);
		if (arr[i] == s)
		{
			S = i;
		}
	}
	//	cerr << S << ' ' << arr[S] << endl;
	for (int i = 0; i < N; i++)
	{
		arr[i] -= sm;
		//		cerr << arr[i] << ' ';
	}
	//	cerr << endl;
	for (int i = 0; i < N; i++)
	{
		if (vis[i])
		{
			continue;
		}
		int u = i;
		do
		{
			vis[u] = true;
			cyc[K].PB(u);
			u = arr[u];
		}
		while(u != i);
		K++;
	}
	for (int i = 0; i < K; i++)
	{
		for (int u : cyc[i])
		{
			id[u] = i;
		}
	}
	for (int i = 0; i < K; i++)
	{
		for (int j = 1; j < cyc[i].size(); j++)
		{
			ans += abs(cyc[i][j] - cyc[i][j - 1]);
		}
		ans += abs(cyc[i].back() - cyc[i][0]);
		lt[i] = INF, rt[i] = -INF;
		for (int u : cyc[i])
		{
			ckmin(lt[i], u);
			ckmax(rt[i], u);
		}
	}
	for (int i = 0; i < N; i++)
	{
		mintable[0][i] = lt[id[i]];
		maxtable[0][i] = rt[id[i]];
		vis[i] = false;
		//		cerr << lt[i] << ' ' << rt[i] << endl;
	}
	for (int i = 0; i <= 20; i++)
	{
		for (int j = (1 << i); j < (2 << i) && j <= N; j++)
		{
			lg2[j] = i;
		}
	}
	for (int i = 1; i <= 20; i++)
	{
		for (int j = 0; j < N; j++)
		{
			if (j + (1 << i) - 1 >= N) continue;
			mintable[i][j] = min(mintable[i - 1][j], mintable[i - 1][j + (1 << (i - 1))]);
			maxtable[i][j] = max(maxtable[i - 1][j], maxtable[i - 1][j + (1 << (i - 1))]);
		}
	}
//	cerr << extend(419, 428).fi << ' ' << extend(419, 428).se << endl;
	pii start = extend(S, S);
	solve(start.fi, start.se);
	ans += dp[start.fi][start.se];
	//u -> arr[u]
	//x -> p[x] -> p[p[x]] etc
	//you can swap, at the cost of the difference in pos
	return ans;
}

Compilation message (stderr)

books.cpp: In function 'll minimum_walk(std::vector<int>, int)':
books.cpp:228:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int j = 0; j < p.size(); j++)
                  ~~^~~~~~~~~~
books.cpp:278:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int j = 1; j < cyc[i].size(); j++)
                   ~~^~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...