停时定理

First Post:

Last Update:

Word Count:
413

Read Time:
1 min

Page View: loading...

本文起因是 HDU ACM 2023 第九场 T8。

Coins

给定长度为 的序列 ,每次随机选取数对 满足 ,使得 ,若 则将其从 中删除,问期望几次操作使得 只有一个数。


我们来看一种很新的科技,考虑使用函数 刻画 的的期望,令 的一次操作之后得到 满足

我们知道终态是唯一且不具有后继状态的,所以如果 存在,那么 就是我们的答案。

我们知道期望具有线性性,所以需要使得 仅包含线性运算,考虑定义 ,那么根据定义就有: 右边没啥意思,来看左边, 表示一次操作总的选择可能性, 表示有 种方案根本就没选到 表示有 种可能性 作为第一操作数,后面一项表示 为第二操作数。

然后解方程: 设个 ,就有 。可以发现 是一个合法的构造,于是得到

然后计算即可。

CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
using ll=__int128;
const int N=1000010,FSIZE=1<<26;
int tn;
ll n,a[N];
char BuF[FSIZE],*InF=BuF,WuF[FSIZE],*OnF=WuF,ST[100],*STC=ST;
template<typename T>void read(T &x){
for(;*InF<33;++InF);
for(x=0;*InF>32;x=x*10+(*InF++^48));
}
void write(ll x){
for(!x&&(*OnF++=48);x;x/=10) *++STC=x%10^48;
for(;STC!=ST;*OnF++=*STC--);
*OnF++='\n';
}
ll f(ll x){return((1+x)*x>>1);}
void work(){
ll sum=0,st=0;
read(n);
for(int i=1;i<=n;++i){
read(a[i]);
st+=f(a[i]);
sum+=a[i];
}
write(f(sum)-st);
}
int main(){
fread(BuF,1,FSIZE,stdin);
for(read(tn);tn--;work());
fwrite(WuF,1,OnF-WuF,stdout);
}