zoukankan      html  css  js  c++  java
  • 【AGC006C】Rabbit Exercise

    题目:

    题目链接:https://atcoder.jp/contests/agc006/tasks/agc006_c
    有 n 只兔子在一个数轴上,兔子为了方便起见从 1 到 n 标号,第 i 只兔子的初始坐标为 xi。兔子会以以下的方式在数轴上锻炼:一轮包含 m 个跳跃,第j个是兔子a[j] (2≤a[j]≤N−1,a是给出的长度为m的数组) 跳一下,这一下从 兔子a[j]− 1 和 兔子a[j] + 1 中等概率的选一个(假设选了 x),那么 a[j]号兔子 会跳到它当前坐标关于x的坐标的对称点。(注意,即使兔子的位置顺序变化了,但是编号仍保持不变,这里按兔子编号算)兔子会进行k轮跳跃,对每个兔子,请你求出它最后坐标的期望值。
    (n,mleq 10^5,|x_i|leq 10^9,kleq 10^{18})

    思路

    首先考虑三只编号连续的兔子 (a,b,c),如果我们让 (b) 跳,那么不难计算出它期望会调到位置 (a+c-b)
    也就是 ((a,b,c) o (a,a+c-b,c))
    我们把两个三元组都做一下差分,得到 ((a,b-a,c-b) o (a,c-b,b-a))
    发现在差分下其实就等价于交换两项。那么我们直接差分出来,然后倍增即可。
    时间复杂度 (O(nlog k+m))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=100010;
    int n,m,nxt[N],id[N],b[N];
    ll k,a[N];
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    	{
    		scanf("%lld",&a[i]);
    		nxt[i]=id[i]=i;
    	}
    	for (int i=n;i>=1;i--)
    		a[i]-=a[i-1];
    	scanf("%d",&m); scanf("%lld",&k);
    	for (int i=1,x;i<=m;i++)
    	{
    		scanf("%d",&x);
    		swap(id[x],id[x+1]);
    	}
    	for (int i=1;i<=n;i++)
    		nxt[id[i]]=i,id[i]=i;
    	for (;k;k>>=1)
    	{
    		if (k&1)
    		{
    			for (int i=1;i<=n;i++) b[nxt[i]]=id[i];
    			memcpy(id,b,sizeof(b));
    		}
    		for (int i=1;i<=n;i++) b[i]=nxt[nxt[i]];
    		memcpy(nxt,b,sizeof(b));
    	}
    	for (int i=1;i<=n;i++)
    	{
    		a[id[i]]+=a[id[i-1]];
    		printf("%lld.0
    ",a[id[i]]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    SPOJ 4487. Can you answer these queries VI splay
    Oracle Enterprise Linux 64-bit 下Oracle11g的监听配置改动及測试步骤
    欧拉函数
    安装Windows7步骤
    在Eclipse中执行、配置Hadoop
    java设计模式演示样例
    VC中获取窗体句柄的各种方法
    HTML5 Canvas中实现绘制一个像素宽的细线
    Java实现 蓝桥杯VIP 基础练习 Sine之舞
    Java实现 蓝桥杯VIP 基础练习 Sine之舞
  • 原文地址:https://www.cnblogs.com/stoorz/p/14349255.html
Copyright © 2011-2022 走看看