可以说是一道思路较为简单但细节巨多,非常难调的题,到处各种加加减减与分类讨论,这么一道水题最后我写了一个半点。
首先我们可以想到,我们认为初始状态为
于是我们直接考虑
不难发现这东西思路显然看起来很简单,但是当实现的时候就会发现阴间的地方在哪了。首先我们发现有四种情况,即
具体情况可以自己画一下然后看看代码,还是比较显然的,只是细节太多了。
xxxxxxxxxx69123
45678910
11using namespace std;12
13mt19937 rnd(random_device{}());14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}15bool rnddd(int x){return rndd(1, 100) <= x;}16
17typedef unsigned int uint;18typedef unsigned long long unll;19typedef long long ll;20typedef long double ld;21
22template < typename T = int >23inline T read(void);24
25int N;26int P[210000];27ll d[210000];28ll ans(LONG_LONG_MAX);29
30int main(){31 N = read();32 for(int i = 0; i <= N - 1; ++i)P[i] = read();33 for(int i = 0; i <= N - 1; ++i)d[0] += min((i - P[i] + N) % N, (P[i] - i + N) % N);34 d[1] = -d[0];35 for(int i = 0; i <= N - 1; ++i)36 if((P[i] - i + N) % N <= (i - P[i] + N) % N){37 int dis = (P[i] - i + N) % N;38 d[1]--, d[dis + 1]++;39 d[dis + 1]++, d[dis + (N >> 1) + 1]--;40 d[dis + (N >> 1) + 1 + (N & 1 ? 1 : 0)]--;41 }else{42 int dis = (i - P[i] + N) % N;43 d[1]++, d[(N >> 1) - dis + 1]--;44 d[(N >> 1) - dis + 1 + (N & 1 ? 1 : 0)]--;45 d[N - dis + 1]++, d[N - dis + 1]++;46 }47 for(int i = 1; i <= N - 1; ++i)d[i] = d[i - 1] + d[i];48 for(int i = 1; i <= N - 1; ++i)d[i] = d[i - 1] + d[i];49 for(int i = 0; i <= N - 1; ++i)ans = min(ans, d[i]);50 printf("%lld\n", ans);51 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);52 return 0;53}54
55template < typename T >56inline T read(void){57 T ret(0);58 int flag(1);59 char c = getchar();60 while(c != '-' && !isdigit(c))c = getchar();61 if(c == '-')flag = -1, c = getchar();62 while(isdigit(c)){63 ret *= 10;64 ret += int(c - '0');65 c = getchar();66 }67 ret *= flag;68 return ret;69}update-2023_01_18 初稿