题目

考虑对于每一个\(a_i\)计算有多少个\(0<x\leq T-1\)满足\(x\equiv a_i(mod\ P)\)且\(x\ mod\ Q \in B\)

显然\(x=a_i+k\times P\),先考虑一下这个\(k\)最大能取到多少,显然有\(a_i+k\times P\leq T-1\),所以\(k\)最大取到\(\left \lfloor \frac{T-1-a_i}{P} \right \rfloor\)

我们这样加下去,肯定会使得\(x\)在\(mod\ Q\)意义下循环,我们尝试利用一下这个循环的性质

一旦\(k\times P\equiv 0(mod\ Q)\)就会循环,显然\(k=\frac{lcm(P,Q)}{P}=\frac{Q}{gcd(P,Q)}\)就是最小循环节

再考虑把这个问题转化成一个图论问题,我们对于每一个\(0<x<Q\),都建一条向\((x+P)\% Q\)的边,属于\(B\)集合中的点的点权是\(1\),我们要做的是求出每一个\(a_i\)走\(\left \lfloor \frac{T-1-a_i}{P} \right \rfloor\)步到达的点的点权和

由于每一个点只有一条出边,那么就说明这个图里只会存在一些简单环,而且每一个环的大小都是\(\frac{Q}{gcd(P,Q)}\)

于是现在我们就可以把每一个环都找出来,维护一下每一个环的点权和,再维护一下环的前缀和,这样我们就能快速计算每一个点走一定步数到达的点的点权和了

边界情况需要好好判断一下

代码

#include <bits/stdc++.h>
#define LL long long
#define re register
const int maxn = 1e6 + 5;
LL T, ans, p[maxn];
std::vector<int> s[maxn], v[maxn];
int len, P, Q, n, m, a[maxn], b[maxn], tax[maxn], w[maxn], col[maxn], pos[maxn], num;
inline int read() {
char c = getchar();int x = 0;
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - 48, c = getchar();
return x;
}
int gcd(int a, int b) { return !b ? a : gcd(b, a % b); }
int dfs(int x, int c) {
if (col[x]) return 0;
col[x] = c;
v[col[x]].push_back(x);
return tax[x] + dfs((x + P) % Q, c);
}
inline int find(int l, int x) { return s[col[x]][pos[x] + l] - s[col[x]][pos[x]]; }
int main() {
P = read(), Q = read(), n = read(), m = read(), scanf("%lld", &T);
for (re int i = 1; i <= n; i++) a[i] = read();
for (re int i = 1; i <= m; i++) b[i] = read();
if (P > Q)
std::swap(P, Q), std::swap(n, m), std::swap(a, b);
len = Q / gcd(P, Q);
for (re int i = 1; i <= m; i++) tax[b[i]] = 1;
for (re int i = 1; i <= n; i++) p[i] = (T - 1 - a[i]) / P;
for (re int i = 0; i < Q; i++)
if (!col[i])
++num, w[num] = dfs(i, num);
for (re int i = 1; i <= num; i++) {
for (re int j = 0; j < v[i].size(); j++) pos[v[i][j]] = j;
int t = v[i].size() - 1;
for (re int j = 0; j < t; j++) v[i].push_back(v[i][j]);
s[i].push_back(tax[v[i][0]]);
for (re int j = 1; j < v[i].size(); j++) s[i].push_back(s[i][j - 1] + tax[v[i][j]]);
}
for (re int i = 1; i <= n; i++) {
ans += 1ll * (p[i] / len) * (w[col[a[i]]]);
ans += find(p[i] % len, a[i]) + tax[a[i]];
}
printf("%lld\n", ans);
return 0;
}

[SNOI2019]数论的更多相关文章

  1. 【LOJ#3096】[SNOI2019]数论

    [LOJ#3096][SNOI2019]数论 题面 LOJ 题解 考虑枚举一个\(A\),然后考虑有多少个合法的\(B\). 首先这个数可以写成\(a_i+kP\)的形式,那么它模\(Q\)的值成环. ...

  2. 【LG5330】[SNOI2019]数论

    [LG5330][SNOI2019]数论 题面 洛谷 题目大意: 给定集合\(\mathbb {A,B}\) 问有多少个小于\(T\)的非负整数\(x\)满足:\(x\)除以\(P\)的余数属于\(\ ...

  3. 洛谷$P5330\ [SNOI2019]$数论 数论

    正解:数论 解题报告: 传送门$QwQ$ ,,,这题还蛮妙的$QwQ$(,,,其实所有数论题对我来说都挺妙的$kk$然后我真的好呆昂我理解了好久$QAQ$ 考虑先建$Q$个点,编号为$[0,Q)$,表 ...

  4. Luogu P5330 [SNOI2019]数论

    题目 如果\(P>Q\)的话我们先交换一下\(P,Q\). 我们先枚举所有满足第一个条件的数,对于\(x\equiv a_i(mod\ P)\),设\(x=a_i+kP(k\in[0,\lflo ...

  5. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  6. 【LOJ】#3096. 「SNOI2019」数论

    LOJ#3096. 「SNOI2019」数论 如果\(P > Q\)我们把\(P\)和\(Q\)换一下,现在默认\(P < Q\) 这个时候每个合法的\(a_i\)都可以直接落到\(Q\) ...

  7. [日常] SNOI2019场外VP记

    SNOI2019场外VP记 教练突然说要考一场别省省选来测试水平...正好还没看题那就当VP咯w... Day 1 八点开题打 .vimrc. 先看了看题目名...一股莫名鬼畜感袭来... 怎么T1就 ...

  8. Codeforces Round #382 Div. 2【数论】

    C. Tennis Championship(递推,斐波那契) 题意:n个人比赛,淘汰制,要求进行比赛双方的胜场数之差小于等于1.问冠军最多能打多少场比赛.题解:因为n太大,感觉是个构造.写写小数据, ...

  9. NOIP2014 uoj20解方程 数论(同余)

    又是数论题 Q&A Q:你TM做数论上瘾了吗 A:没办法我数论太差了,得多练(shui)啊 题意 题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, ...

随机推荐

  1. Button Style

    Button Style BS_3STATE 与复选框一样本样式按钮可被单击变暗.变暗状态通常用于指示本样式的按键正处于禁用状态. BS_AUTO3STATE 与三状态的复选框一样当用户选中它本按钮样 ...

  2. 2.27 MapReduce Shuffle过程如何在Job中进行设置

    一.shuffle过程 总的来说: *分区 partitioner *排序 sort *copy (用户无法干涉) 拷贝 *分组 group 可设置 *压缩 compress *combiner ma ...

  3. 鸟哥私房菜基础篇:安裝 CentOS7.x习题

    猫宁!!! 参考链接:http://linux.vbird.org/linux_basic/0157installcentos7.php 鸟哥是为中国信息技术发展做出巨大贡献的人. 1-Linux的目 ...

  4. 利用pyinstaller生成exe文件碰到的一些问题及解决方法

    在“开源图像标注工具labelme的安装使用及汉化”这篇博客中,使用pyinstaller将labelme项目的入口python文件main.py打包,生成了main.exe文件,可以在Windows ...

  5. PyCharm - 格式化代码 (Reformat Code)

    1. Ctrl + A全选代码. 2. Code -> Reformat Code

  6. 进程与线程(3)- python实现多线程

    参考链接: https://www.jianshu.com/p/415976668b97?utm_campaign=maleskine&utm_content=note&utm_med ...

  7. Jquery | 基础 | 慕课网 | 类选择器

    原生getElementsByClassName()函数的实现代码与jQuery实现代码的比较: <!DOCTYPE html> <html> <head> < ...

  8. 数学 2015百度之星初赛2 HDOJ 5255 魔法因子

    题目传送门 /* 数学:不会写,学习一下这种解题方式:) 思路:设符合条件的数的最高位是h,最低位是l,中间不变的部分为mid,由题意可得到下面的公式(这里对X乘上1e6用a表示,b表示1e6) (h ...

  9. vue+typescript入门学习

    最近想要结合vue学习typescript,了解到vue2.5之后开始支持typescript,就像拿vue学习一下,首先要解决的就是环境的搭建,略微麻烦,如果想要自己体验一把,可以参考这篇文章htt ...

  10. (023) 关于51单片机的A5指令

    可看见一篇讲51单片机加密的文章这么讲: [加密方法:在A5后加一个二字节或三字节操作码,因为所有反汇编软件都不会反汇编A5指令,造成正常程序反汇编乱套,执行程序无问题仿制者就不能改变你的源程序.] ...