@description@

给定 n, a, b, p,其中 n, a 互质。定义一个长度为 n 的 01 串 c[0..n-1],其中 c[i] == 0 当且仅当 (ai+b) mod n < p。

给定一个长为 m 的小 01 串,求出小串在大串中出现了几次。

input

第一行包含整数 n, a, b, p, m (2<=n<=10^9, 1<=p, a, b, m<n, 1<=m<=10^6)。n 和 a 互质。

第二行一个长度为 m 的 01 串。

output

一个整数,表示小串在大串中出现了几次

sample input

9 5 6 4 3

101

sample output

3

sample explain

@solution@

假如某次出现,小 01 串的第 1 个位置对应大 01 串的第 i 个位置(i <= n - m),令 x = (ai + b) mod n。

如果小 01 串的第 1 个为 0,则 x < p;否则 x >= p。

如果小 01 串的第 2 个为 0,则 (x + a) mod n < p;否则 (x + a) mod n >= p。

……

如果小 01 串的第 i 个为 0,则 (x + a*i) mod n < p;否则 (x + a*i) mod n >= p。

我们可以解模意义下的不等式,将所有不等式的解集取交集就可以求出满足条件的 x,然后判断 x 对应的 i 是否满足 i <= n - m。

但是这个算法虽然正确,细节方面仍然不是很清晰。

解不等式可以分类讨论,也可以这样来理解:

对于 (x + a*i) mod n < p,可以理解为由点 x 出发在模意义下移动 a*i 步到达区间 [0, p - 1]。

我们可以相对运动:区间 [0, p - 1] 在模意义下反向移动 a*i 步,就是不等式 (x + a*i) mod n < p 的解集。

由于是在模意义下移动,最终的解集区间形如 [l, r] 或 [l, n)∪[0, r]。

然而问题就来了:如果一些解集长成 [l, n)∪[0, r] 的形式,所有解集的交集就可能长得非常的奇怪(因为我们相当于求集合并集的交集),如果暴力取交我们可能需要 O(n^2) 的时间完成。

一种简洁的解决方案是用补集思想。我们知道,集合先取交集再取补集 = 集合先取补集再取并集。

我们一开始将所有解集取补集(因为是区间形式,这个很容易实现),然后就是区间并问题,排序+扫描一遍可以搞定。最后将集合并集再取补集就可以了。

同时,这也允许我们将 i > n-m 这些不合法的情况当作合法情况的补集,跟上面的一起取并集。

@accepted code@

#include<set>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1000000;
struct segment{
int le, ri;
segment(int _l=0, int _r=0):le(_l), ri(_r){}
}seg[3*MAXN + 5];
bool operator < (segment a, segment b) {
return a.le < b.le;
}
char s[MAXN + 5];
int main() {
int n, a, b, p, m;
scanf("%d%d%d%d%d", &n, &a, &b, &p, &m);
scanf("%s", s);
int cnt = 0;
for(int i=0;i<m;i++) {
int tmp = (n - 1LL*i*a%n)%n, le, ri;
if( s[i] == '0' )
le = tmp%n, ri = (p + tmp - 1)%n;
else le = (p + tmp)%n, ri = (n + tmp - 1)%n;
if( le <= ri )
seg[++cnt] = segment(0, le - 1), seg[++cnt] = segment(ri + 1, n - 1);
else seg[++cnt] = segment(ri + 1, le - 1);
}
for(int i=n-1;i>n-m;i--) {
int tmp = (1LL*a*i%n + b)%n;
cnt++, seg[cnt].le = tmp, seg[cnt].ri = tmp;
}
cnt++, seg[cnt].le = n, seg[cnt].ri = n;
sort(seg + 1, seg + cnt + 1);
int ans = 0, ri = -1;
for(int i=1;i<=cnt;i++) {
if( seg[i].le <= ri )
ri = max(ri, seg[i].ri);
else {
ans += max(0, seg[i].le - ri - 1);
ri = seg[i].ri;
}
}
printf("%d\n", ans);
}

@details@

一开始想得很简单,没有想到 [l, n)∪[0, r] 这样的集合取交集会出现断断续续的区间,弄得我……想要吐血了。

后来的做法也是用了补集,但只有 [l, n)∪[0, r] 才取补集,因为它们取补集之后就变成了一个正常的线段 [r + 1, l - 1] 了。

实测上面的做法要比全部去补集的常数小一些。

@bzoj - 4377@ [POI2015] Kurs szybkiego czytania的更多相关文章

  1. BZOJ4377 : [POI2015]Kurs szybkiego czytania

    因为$a$与$n$互质,所以对于$0$到$n-1$里每个$i$,$ai\bmod n$的值互不相同. 设匹配成功的起点为$i$,那么可以得到$3m$段$ai\bmod n$的值不能取的禁区,每段都是连 ...

  2. BZOJ4377[POI2015]Kurs szybkiego czytania——数学思维题

    题目描述 给定n,a,b,p,其中n,a互质.定义一个长度为n的01串c[0..n-1],其中c[i]==0当且仅当(ai+b) mod n < p.给定一个长为m的小01串,求出小串在大串中出 ...

  3. BZOJ4377 Kurs szybkiego czytania \ Luogu 3589[POI2015]KUR - 数学思维题

    Solution 我又双叒叕去看题解啦$QAQ$, 真的想不到鸭 输入 $a$ 和 $n$ 互质, 所以满足 $a \times i \ mod \ n$ $(0<=i<n)$ 肯定是不重 ...

  4. bzoj 4386: [POI2015]Wycieczki

    bzoj 4386: [POI2015]Wycieczki 这题什么素质,爆long long就算了,连int128都爆……最后还是用long double卡过的……而且可能是我本身自带大常数吧,T了 ...

  5. BZOJ 4385: [POI2015]Wilcze doły

    4385: [POI2015]Wilcze doły Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 648  Solved: 263[Submit][ ...

  6. BZOJ 4384: [POI2015]Trzy wieże

    4384: [POI2015]Trzy wieże Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 217  Solved: 61[Submit][St ...

  7. Bzoj 3747: [POI2015]Kinoman 线段树

    3747: [POI2015]Kinoman Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 553  Solved: 222[Submit][Stat ...

  8. BZOJ 3747 POI2015 Kinoman 段树

    标题效果:有m点,每个点都有一个权值.现在我们有这个m为点的长度n该序列,寻求区间,它仅出现一次在正确的点区间内值和最大 想了很久,甚至神标题,奔说是水的问题--我醉了 枚举左点 对于每个请求留点右键 ...

  9. BZOJ 4380 [POI2015]Myjnie | DP

    链接 BZOJ 4380 题面 有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i]. 有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[i]个洗车店,且会选择这些店中最便宜的一个 ...

随机推荐

  1. CentOS7系统ifconfig无法使用的解决方法

    在使用RAKsmart美国服务器的时候,如果安装的CentOS7操作系统的话,可能会经常用到“ifconfig”命令.ifconfig命令大多是用于CentOS 6版本下面,主要用于查看网卡配置信息. ...

  2. NOIP模拟 9.09

    AK300分 果实计数 (count.pas/.c/.cpp) 时间限制:1s,空间限制32MB 题目描述: 淘淘家有棵奇怪的苹果树,这棵树共有n+1层,标号为0~n.这棵树第0层只有一个节点,为根节 ...

  3. 【CS Round #44 (Div. 2 only) B】Square Cover

    [链接]点击打开链接 [题意] 给你一个n*m的矩形,让你在其中圈出若干个子正方形,使得这些子正方形里面的所有数字都是一样的. 且一样的数字,都是在同一个正方形里面.问你有没有方案. [题解] 相同的 ...

  4. HR招聘_(七)_招聘方法论(面试环节·动机判断)

    候选人选择一般会看硬性技能,软性技能,动机意愿三个方面的匹配程度,硬性技能主要指纵向的业务能力,部门面试官也会着重看这方面,软性技能包括沟通,情商,气质等.动机意愿非常重要,再优秀的如果没有意愿,动机 ...

  5. Linux常用命令操作详解

    https://mp.weixin.qq.com/s/IR4yy7Q0mOA_XV16R21CdQ 一:Linux下tomcat服务的启动.关闭与错误跟踪 使用PuTTy远程连接到服务器以后,通常通过 ...

  6. Yann LeCun清华演讲:深度学习与人工智能的未来

    2017年3月22日下午,Facebook人工智能研究院院长.纽约大学终身教授Yann LeCun在清华大学大礼堂为校内师生以及慕名而来的业内人士呈现了一场主题为<深度学习与人工智能的未来(De ...

  7. ASP.NET+C#面试题

    1.维护数据库的完整性.一致性.你喜欢用触发器还是自写业务逻辑?为什么? 尽可能用约束(包括CHECK.主键.唯一键.外键.非空字段)实现,这种方式的效率最好:其次用触发器,这种方式可以保证无论何种业 ...

  8. Python subn函数

  9. 人物-旅行-潘德明-Info:《近代中国徒步环游世界第一人:潘德明 》

    ylbtech-人物-旅行-潘德明-Info:<近代中国徒步环游世界第一人:潘德明 > 1.返回顶部 1. 近代中国徒步环游世界第一人:潘德明 2016-10-12 18:01 “以世界为 ...

  10. .net WebServer示例及调用(接口WSDL动态调用 JAVA)

    新建.asmx页面 using System; using System.Collections.Generic; using System.Linq; using System.Web; using ...