• [洛谷] AT2164 [AGC006C] Rabbit Exercise


    Description

    (Link)

    Solution

    一道好题,涉及到差分化简以及倍增求置换。

    注意到一次操作后,(a[i])的位置期望为(E(a[i])=frac{1}{2}(E(2a[i+1]-a[i])+E(2a[i-1]-a[i]))=E(a[i+1]+a[i-1]-a[i]))

    这么看不太好求。但对(a)差分后,发现一次这样的操作就是对差分数组(d)进行(swap(d[i],d[i+1]))

    那么就是对(d)进行(k)轮置换。注意到(k)很大,可以通过倍增优化,和快速幂类似。

    即我们记录两个数组(p)(q)(p)保存置换一轮后的结果,相当于快速幂的(base)。而(q)保存答案即可。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    
    int n, m, x[100005], p[100005], q[100005], a[100005], cnt[100005];
    
    ll sum, k;
    
    int read()
    {
    	int x = 0, fl = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0'; ch = getchar();}
    	return x * fl;
    }
    
    int main()
    {
    	n = read();
    	for (int i = 1; i <= n; i ++ )
    	{
    		x[i] = read();
    		p[i] = q[i] = i;
    	}
    	m = read(); scanf("%lld", &k);
    	for (int i = 1; i <= m; i ++ )
    	{
    		a[i] = read();
    		swap(p[a[i]], p[a[i] + 1]);
    	}
    	while (k)
    	{
    //		printf("%lld
    ", k);
    		if (k & 1ll)
    		{
    			for (int i = 1; i <= n; i ++ )
    				cnt[i] = q[p[i]];
    			for (int i = 1; i <= n; i ++ )
    				q[i] = cnt[i];
    		}
    		for (int i = 1; i <= n; i ++ )
    			cnt[i] = p[p[i]];
    		for (int i = 1; i <= n; i ++ )
    			p[i] = cnt[i];
    		k >>= 1ll;
    	}
    	for (int i = 1; i <= n; i ++ )
    	{
    		sum += (ll)(x[q[i]] - x[q[i] - 1]);
    		printf("%.1lf
    ", (double)(sum));
    	}
    	return 0;
    }
    
  • 相关阅读:
    Dagger2 (二) 进阶篇
    Dagger2 (一) 入坑篇
    RoboGuice 3.0 (三)总结篇
    RoboGuice 3.0 (二)进阶篇
    RoboGuice 3.0 (一)入坑篇
    spring源码
    Java transient关键字使用
    Spring源码学习
    jvm系列(一):java类的加载机制
    Java中newInstance()和new()
  • 原文地址:https://www.cnblogs.com/andysj/p/14435892.html
Copyright © 2020-2023  润新知