• AGC006C Rabbit Exercise


    题目链接

    problem

    (n)个兔子站成一排,每只兔子有自己的位置,有(m)次操作,第(i)次操作将(a_i)以相等的概率挪到关于(a_{i-1})对称的位置或挪到与(a_{i+1})对称的位置。
    将这m次操作进行K轮。
    问最终每只兔子位置坐标的期望。

    solution

    对于第(a_i)个兔子,设(a_i-a_{i-1}=x,a_{i+1}-a_i=y)。那么如果选择关于(a_{i-1})对称,所到达的位置就是(l=a_{i-1}-x)。同样的,如果选择关于(a_{i+1})对称,到达的位置就是(r=a_{i+1}+y),根据期望的线性性,第(i)只兔子所在坐标的期望就是(t=frac{l+r}{2})。显然(t-l=r-t=x+y)。又因为(a_{i-1}-l=x,r-a_{i+1}=y)。所以就有(t-a_{i-1}=y,a_{i+1}-t=x)

    (d_i=a_i-a_{i-1}),对于第(i)个兔子进行一次操作,就相当于交换了(d_i)(d_{i+1})

    那么做法就很简单了,先根据(m)操作求出一个置换,然后利用快速幂计算置换(K)次后的答案。

    复杂度(O(nlogK))

    code

    /*
    * @Author: wxyww
    * @Date:   2020-05-21 15:53:33
    * @Last Modified time: 2020-05-21 16:09:36
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<ctime>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int N = 200010;
    #define int ll
    ll read() {
    	ll x = 0,f = 1;char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1; c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		x = x * 10 + c - '0'; c = getchar();
    	}
    	return x * f;
    }
    int n;
    ll tmp[N];
    void mul(int *a,int *b) {
    	for(int i = 1;i <= n;++i) {
    		tmp[i] = a[b[i]];
    	}
    	for(int i = 1;i <= n;++i) a[i] = tmp[i];
    }
    int a[N],p[N];
    void qm(ll y) {
    	int ret[N];
    	for(int i = 1;i <= n;++i) ret[i] = i;
    
    	for(;y;y >>= 1,mul(p,p))
    		if(y & 1) mul(ret,p);
    	for(int i = 1;i <= n;++i) p[i] = ret[i];
    }
    signed main() {
    	n = read();
    	for(int i = 1;i <= n;++i) {
    		a[i] = read();p[i] = i;
    	}
    	
    	int m = read();ll K = read();
    	
    	for(int i = n;i >= 1;--i) a[i] -= a[i - 1];
    	
    	for(int i = 1;i <= m;++i) {
    		int x = read();
    		swap(p[x],p[x + 1]);
    	}
    
    	qm(K);
    
    	for(int i = 1;i <= n;++i) tmp[i] = a[p[i]];
    	// for(int i = 1;i <= n;++i) printf("%d ",tmp[i]);
    	// puts("");
    	for(int i = 1;i <= n;++i) {
    		printf("%lld.0
    ",tmp[i] += tmp[i - 1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    jdbc基础
    JavaScrip练习
    EL标签
    javaBean和mvc思想
    jsp
    Session
    Cookie
    ServletConfig
    c++、opencv、泊松融合
    目标检测、Iou、nms、soft_nms、
  • 原文地址:https://www.cnblogs.com/wxyww/p/agc006c.html
Copyright © 2020-2023  润新知