HDU-6874 Decision 倍增 (2020 HDU多校 D7 D)

Decision

题意

[0,t] 中等概率的选取两个数字 v1,v2, 定义序列 XX0=v1+v2,Xn+1=(aXn+c)modm。如果 X|v1v2| 是偶数,则获胜,求获胜概率

范围:2m106,0a,c<m,0t<m2

分析

枚举 sum=v1+v2 的值,考虑 dis=|v1v2| 的可能取值。

先考虑sumt 的情况

  • sum 是偶数,那么dis 可能取值为 0,2,sum, 并且0只会被取到一次,其他偶数会取到两次(为什么会取到两次?考虑 v1v2 对称取值)。
  • sum 是奇数,那么dis 可能取值为 1,3,sum, 所有数字都会取到两次

然后sum>t 的情况类似

  • sum 是偶数,那么dis 可能取值为 0,2,2tsum, 并且0只会被取到一次,其他偶数会取到两次。
  • sum 是奇数,那么dis 可能取值为 1,3,2tsum, 所有数字都会取到两次

现在的问题是如何快速根据sum, 求出所有值的贡献,注意到 X0=sum, 同组 dis 都只会隔2递增,我们可以预处理出每个sum往后跳两次的位置在哪里(跳是指 sum=(asum+c)(modm)), 然后倍增处理即可。

const int N = 1000000 + 5;
int T, t, a, c, m;
int nxt[N], tt;
int f[N][21], d[N][21];
ll res;
void get(int x, int p){
for(int i=tt;i>=0;i--){
if(p >= (1 << i)){
res += 2*d[x][i]; // 每个dis的贡献都是二倍
p -= 1 << i;
x = f[x][i];
}
}
}
ll gcd(ll a, ll b){return b == 0 ? a : gcd(b, a%b);}
int main(){
scanf("%d", &T);
while(T--){
scanf("%d%d%d%d",&t, &a, &c, &m);
for(int i=0;i<m;i++){
nxt[i] = (1ll * a * i + c) % m; //nxt[i] 表示 i 往后跳一次的位置
}
for(int i=0;i<m;i++){
f[i][0] = nxt[nxt[i]]; // f[i][0] 表示 i 往后跳2^i次的位置
// d 数组计算贡献,当坐标为偶数时贡献为 1,注意这里并没有计算起点 i 的贡献,后面需要单独计算
d[i][0] = f[i][0] % 2 == 0;
}
tt = log2(2*t-1) + 1;
for(int j=1;j<=tt;j++) {
for(int i=0;i<m;i++){
f[i][j] = f[f[i][j-1]][j-1];
d[i][j] = d[i][j-1] + d[f[i][j-1]][j-1];
}
}
res = 0;
// 枚举 sum
for(int i=0;i<=2*t;i++) {
if(i <= t) {
if(i % 2 == 0) {
res ++; // sum 为偶数,dis 为 0 时有一次贡献
get(i, i / 2); // 计算之后的贡献,跳跃次数为 sum / 2
} else {
// sum 为奇数,单独计算 dis 为 1 时的贡献
if(nxt[i] % 2 == 0) res += 2;
// 从 nxt[i] 开始,计算剩下的贡献
get(nxt[i], (i - 1) / 2);
}
} else {
if(i % 2 == 0) {
res ++;
get(i, (2 * t - i)/2);
} else {
if(nxt[i] % 2 == 0) res += 2;
get(nxt[i], (2 * t - i - 1) / 2);
}
}
}
ll all = 1ll*(t + 1) * (t + 1);
ll g = gcd(all, res);
printf("%lld/%lld\n", res/g, all/g);
}
return 0;
}

其他: 场上并没有想出这道题,列出X关于sum和dis的通项之后手足无措,sum和dis奇偶性保持一致,sum确定后,dis是等间隔取到的,但是仍然没有想到可以用倍增处理。

本文作者:kpole

本文链接:https://www.cnblogs.com/1625--H/p/13491037.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   kpole  阅读(305)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起