首先我们可以考虑一下 \(x\) 关于 \(y\) 的对称点的坐标,不难发现就是 \(x + 2 \times (y - x)\),那么期望的增量就会增加 \(2 \times (y - x)\)。不难发现我们可以令 \(dp_{i, j}\) 表示 \(j\) 第 \(i\) 次操作(即假设进行了 \(p\) 轮操作,当前是第 \(q\) 次操作,则 \(i = (p - 1) \times m + q\)),则会有转移:

\[dp_{i, a_q} += \frac{1}{2} \times 2 \times (dp_{i - 1, a_q - 1} - dp_{i - 1, a_q}) + \frac{1}{2} \times 2 \times (dp_{i - 1, a_q + 1} - dp_{i - 1, a_q})
\]

即:

\[dp_{i, a_q} += dp_{i - 1, a_q - 1} + dp_{i - 1, a_q + 1} - 2 \times dp_{a_q}
\]

可以发现第一维可以直接压去,则有转移 \(i = a_q\):

\[dp_i += dp_{i - 1} + dp_{i + 1} - 2 \times dp_i
\]

你会发现这个转移非常有特色,实际上可以将上式划成两个部分:

\[dp_i += (dp_{i + 1} - dp_i) - (dp_i - dp_{i - 1})
\]

你会发现这实际上是两个差分数在相加,令 \(f_i = dp_i - dp_{i - 1}\),即:

\[dp_i = f_{i + 1} - f_i
\]

显然这样算是非常不方便的,我们干脆考虑差分数组 \(f\) 的变化,则有:

\[f_i += f_{i + 1} - f_i \Leftrightarrow f_i = f_{i + 1}
\]
\[f_{i + 1} -= f_{i + 1} - f_i \Leftrightarrow f_{i + 1} = f_i
\]

相当于将差分数组 \(f_i, f_{i + 1}\) 交换!那么问题转化为,给你一个序列,有 \(K\) 轮变换,每次变换有 \(m\) 次操作,按照给定的操作序列 \(a_i\) 交换 \(f_{a_i}, f_{a_i + 1}\)。因为每轮变换的操作序列都是一样的,这意味着每个位置在一轮之后变到的位置是一样的。于是我们先暴力将经过一轮操作后位置排列 \(P\) 变换到的位置序列 \(P'\)(事实上我们成排列 \(P \rightarrow P'\) 的这样一个过程叫做置换),对于置换而言一个常见的想法就是对 \(P_i \rightarrow P'_i\) 连一条边,这样将形成一张若干个简单环组成的有向图。那么每个位置经过 \(K\) 轮置换后的位置就相当于它在这个简单环上走 \(K\) 步后的位置,这个就很容易可以算出来了。

可以发现,上面这个做法的复杂度是 \(O(n + m)\) 的,非常地优秀!

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i, l, r) for(int i = l; i <= r; ++i)
const int N = 100000 + 5;
bool book[N];
int n, m, k, tmp, cnt, a[N], d[N], p[N], dp[N], nxt[N], ans[N];
vector <int> G[N];
int read(){
char c; int x = 0, f = 1;
c = getchar();
while(c > '9' || c < '0'){ if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
signed main(){
n = read();
rep(i, 1, n) d[i] = read(), p[i] = i, dp[i] = d[i] - d[i - 1];
m = read(), k = read();
rep(i, 1, m) a[i] = read(), swap(p[a[i]], p[a[i] + 1]);
rep(i, 1, n) nxt[i] = p[i];
rep(i, 1, n) if(!book[i]){
int x = i; G[++cnt].push_back(i), book[i] = true;
while(nxt[x] != i) x = nxt[x], book[x] = true, G[cnt].push_back(x);
}
rep(i, 1, cnt){
int S = G[i].size(), tr = k % S;
rep(j, 0, S - 1) ans[G[i][j]] = dp[G[i][(j + tr) % S]];
}
rep(i, 1, n) tmp += ans[i], printf("%lld.0\n", tmp);
return 0;
}

AT2164 [AGC006C] Rabbit Exercise的更多相关文章

  1. [AT2164] [agc006_c] Rabbit Exercise

    题目链接 AtCoder:https://agc006.contest.atcoder.jp/tasks/agc006_c 洛谷:https://www.luogu.org/problemnew/sh ...

  2. 【做题】agc006C - Rabbit Exercise——模型转换

    原文链接https://www.cnblogs.com/cly-none/p/9745177.html 题意:数轴上有\(n\)个点,从\(1\)到\(n\)编号.有\(m\)个操作,每次操作给出一个 ...

  3. AGC006C Rabbit Exercise

    传送门 设 \(f_{i,j}\) 表示兔子 \(i\) 在当前 \(j\) 轮的期望位置 对于一次操作 \(f_{i,j+1}=\frac{1}{2}(2f_{i-1,j}-f_{i,j})+\fr ...

  4. 【agc006C】Rabbit Exercise

    Portal --> agc006C Solution 啊感觉是好有意思的一道题qwq官方题解里面的说辞也是够皮的哈哈哈..(大概就是说如果你没有意识到那个trick的话这题这辈子都做不出来qw ...

  5. 【AGC006C】Rabbit Exercise 置换

    题目描述 有\(n\)只兔子站在数轴上.为了方便,将这些兔子标号为\(1\ldots n\).第\(i\)只兔子的初始位置为\(a_i\). 现在这些兔子会按照下面的规则做若干套体操.每一套体操由\( ...

  6. AT2164 Rabbit Exercise

    传送门 解题思路 首先考虑k=1的情况,对于每一个a[i],它可能会到a[i-1]*2-a[i] 与 a[i+1]*2-a[i]两个位置,概率都为%50,那么它的期望位置为 (a[i-1]*2-a[i ...

  7. 【AtCoder】【思维】【置换】Rabbit Exercise

    题意: 有n只兔子,i号兔子开始的时候在a[i]号位置.每一轮操作都将若干只兔子依次进行操作: 加入操作的是b[i]号兔子,就将b[i]号兔子移动到关于b[i]-1号兔子现在所在的位置对称的地方,或者 ...

  8. AtCoder Grand Contest 006 (AGC006) C - Rabbit Exercise 概率期望

    原文链接https://www.cnblogs.com/zhouzhendong/p/AGC006C.html 题目传送门 - AGC006C 题意 有 $n$ 个兔子,从 $1$ 到 $n$ 编号, ...

  9. [Atcoder Grand 006 C] Rabbit Exercise 解题报告 (期望)

    题目链接:https://www.luogu.org/problemnew/show/AT2164 https://agc006.contest.atcoder.jp/tasks/agc006_c 题 ...

随机推荐

  1. C# 后台发送get,post请求及WebApi接收

    后台发送get请求 1.发送带参数的get请求 /// <summary> /// 发送get请求 参数拼接在url后面 /// </summary> /// <para ...

  2. windows下的pycharm下载与安装(不包括激活)

    Pycharm的下载与安装 首先兄弟们我们依旧在浏览器输入pycharm的网址链接 PyCharm: the Python IDE for Professional Developers by Jet ...

  3. .net core的配置介绍(一):IConfiguration

    说到配置,绝大部分系统都会有配置,不需要配置的系统是非常少的,想想以前做.net 开发时,我们常常将配置放到web.config中,然后使用ConfigurationManager去读取. 初次接触到 ...

  4. 【操作系统】I/O多路复用 select poll epoll

    @ 目录 I/O模式 I/O多路复用 select poll epoll 事件触发模式 I/O模式 阻塞I/O 非阻塞I/O I/O多路复用 信号驱动I/O 异步I/O I/O多路复用 I/O 多路复 ...

  5. websocket在线测试工具

    为了测试websocket, 根据网上的一些工具修改了一些, 因此得到了这个工具 源码 源码: <!DOCTYPE html> <html lang="en"&g ...

  6. [Blue Prism] Data item 的使用

      1.用于存储各种数据类型的变量,支持的数据类型如下: Binary - 用于存储二进制 blob,例如文本文件. Date - 用于存储日期. 此数据类型与 DateTime 类似,只是 Date ...

  7. 什么是LTV,舔狗的LTV可以乘以N吗?

    依旧注意一下,数据类文章比较敏感,舔狗只是代词,千万不要以为我是舔狗. 之前我们探讨过如何对自己的用户进行分层:不知怎么选,用RFM模型看舔狗质量! 也探讨了如何判断自己适不适合海后(主播)这个业务: ...

  8. Go语言系列之包

    Go语言的包(package) 一.包介绍 包(package)是多个Go源码的集合,是一种高级的代码复用方案,Go语言为我们提供了很多内置包,如fmt.os.io等. 二.定义包 我们还可以根据自己 ...

  9. 微服务架构攀登之路(四)之使用gRPC构建微服务

    做一个处理用户信息的微服务 客户端通过用户名,可以从服务端查询用户的基本信息 gRPC proto user.proto 定义客户端请求.服务端响应的数据格式 user.pb.go 自动生成的,为数据 ...

  10. SpringBoot学习笔记一之本地环境基础搭建

    原文链接: https://www.toutiao.com/i6802935050196222471/ 工程创建 Maven创建工程 搜索maven找到project的创建 创建simple proj ...