HDU-6874 Decision 倍增 (2020 HDU多校 D7 D)
Decision
题意
从 \([0,t]\) 中等概率的选取两个数字 \(v_1,v_2\), 定义序列 \(X\) 有 \(X_0=v1+v2,X_{n+1}=(aX_n+c) \mod m\)。如果 \(X_{|v1-v2|}\) 是偶数,则获胜,求获胜概率
范围:\(2\le m \le 10^6,0\le a,c \lt m, 0\le t \lt \frac{m}{2}\)
分析
枚举 \(sum = v_1+v_2\) 的值,考虑 \(dis = |v_1-v_2|\) 的可能取值。
先考虑\(sum \le t\) 的情况
- 若 \(sum\) 是偶数,那么\(dis\) 可能取值为 \(0,2,\cdots sum\), 并且0只会被取到一次,其他偶数会取到两次(为什么会取到两次?考虑 \(v_1\)与\(v_2\) 对称取值)。
- 若 \(sum\) 是奇数,那么\(dis\) 可能取值为 \(1,3,\cdots sum\), 所有数字都会取到两次
然后\(sum\gt t\) 的情况类似
- 若 \(sum\) 是偶数,那么\(dis\) 可能取值为 \(0,2,\cdots 2*t-sum\), 并且0只会被取到一次,其他偶数会取到两次。
- 若 \(sum\) 是奇数,那么\(dis\) 可能取值为 \(1,3,\cdots 2*t-sum\), 所有数字都会取到两次
现在的问题是如何快速根据\(sum\), 求出所有值的贡献,注意到 \(X_0=sum\), 同组 \(dis\) 都只会隔2递增,我们可以预处理出每个sum往后跳两次的位置在哪里(跳是指 \(sum' = (a*sum+c)\pmod m\)), 然后倍增处理即可。
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是等间隔取到的,但是仍然没有想到可以用倍增处理。
HDU-6874 Decision 倍增 (2020 HDU多校 D7 D)的更多相关文章
- HDU 3784 继续xxx定律 & HDU 2578 Dating with girls(1)
HDU 3784 继续xxx定律 HDU 2578 Dating with girls(1) 做3748之前要先做xxx定律 对于一个数n,如果是偶数,就把n砍掉一半:如果是奇数,把n变成 3*n+ ...
- HDU 4352 XHXJ's LIS HDU(数位DP)
HDU 4352 XHXJ's LIS HDU 题目大意 给你L到R区间,和一个数字K,然后让你求L到R区间之内满足最长上升子序列长度为K的数字有多少个 solution 简洁明了的题意总是让人无从下 ...
- hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 题意:给你n个墓室,m条路径,一个人在1号墓室(起点),另一个人在n号墓室(终点),起点的那 ...
- hdu 5319 Painter(杭电多校赛第三场)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5319 Painter Time Limit: 2000/1000 MS (Java/Others) ...
- hdu 5326 Work(杭电多校赛第三场)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5326 Work Time Limit: 2000/1000 MS (Java/Others) M ...
- HDU 5361 In Touch (2015 多校6 1009 最短路 + 区间更新)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5361 题意:最短路.求源点到全部点的最短距离.但与普通最短路不同的是,给出的边是某点到区间[l,r]内随意 ...
- HDU 5402 Travelling Salesman Problem(多校9 模拟)
题目链接:pid=5402">http://acm.hdu.edu.cn/showproblem.php?pid=5402 题意:给出一个n×m的矩阵,位置(i.j)有一个非负权值. ...
- hdu 4950 Monster(数学题,多校8)
题目链接:pid=4950http://acm.hdu.edu.cn/showproblem.php?pid=4950">http://acm.hdu.edu.cn/showprobl ...
- HDU 5317 RGCDQ(素数个数 多校2015啊)
题目链接:pid=5317" target="_blank">http://acm.hdu.edu.cn/showproblem.php?pid=5317 Prob ...
随机推荐
- 多年经验,教你写出最惊艳的 Markdown 高级用法
点赞再看,养成习惯,微信搜索[高级前端进阶]关注我. 本文 GitHub https://github.com/yygmind 已收录,有一线大厂面试完整考点和系列文章,欢迎 Star. 最近在学习的 ...
- Nebula Exchange 工具 Hive 数据导入的踩坑之旅
摘要:本文由社区用户 xrfinbj 贡献,主要介绍 Exchange 工具从 Hive 数仓导入数据到 Nebula Graph 的流程及相关的注意事项. 1 背景 公司内部有使用图数据库的场景,内 ...
- Facetoobject_encapsulation
面向对象程序设计思想 一.思想 处处皆对象. 当提到某一功能时,首先应该想有没有实现该功能的对象,有则调用,没有则创建类.当提到数据时,应该想到属于哪个对象. 1.求1~n的累加和 public cl ...
- sql查询速度慢分析及如何优化查询
原因分析后台数据库中数据过多,未做数据优化数据请求-解析-展示处理不当 网络问题提高数据库查询的速度方案SQL 查询速度慢的原因有很多,常见的有以下几种:1.没有索引或者没有用到索引(查询慢最常见的问 ...
- 笔记:学习go语言的网络基础库,并尝试搭一个简易Web框架
在日常的 web 开发中,后端人员常基于现有的 web 框架进行开发.但单纯会用框架总感觉不太踏实,所以有空的时候还是看看这些框架是怎么实现的会比较好,万一要排查问题也快一些. 最近在学习 go 语言 ...
- JavaScript 获得当前日期+时间
//直接从项目中copy出来的,亲测可用.function getTodayTime(){ var date = new Date(); var seperator1 = "-"; ...
- LeetCode844 比较含退格的字符串
题目描述: 给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果. # 代表退格字符. 示例 1: 输入:S = "ab#c", T = ...
- Mybatis 一级缓存和二级缓存的使用
目录 Mybatis缓存 一级缓存 二级缓存 缓存原理 Mybatis缓存 官方文档:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache My ...
- CF76A Gift
题目描述 有一个国家有N个城市和M条道路,这些道路可能连接相同的城市,也有可能两个城市之间有多条道路. 有一天,有一伙强盗占领了这个国家的所有的道路.他们要求国王献给他们礼物,进而根据礼物的多少而放弃 ...
- 微信小程序腾讯地图SDK使用方法
一.本篇文章主要知识点有以下几种: 1.授权当前位置 2.map组件的使用 3.腾讯地图逆地址解析 4.坐标系的转化 二.效果如下: 三.WXML代码 <map id="map&quo ...