【题解】[POI2015] KUR

题意

给你一个长度为 n01 序列,每一个数位是 0 当且仅当 (a*i+b) mod n < p 。求长度为 m01 串出现了几次。

Solution:

数论+集合求交。

首先考虑互质,所以 a*i 互不相同。如果我们枚举序列开头 x ,可以得到 m-1 个关于 a*ip 意义下的不等式,又因为 a*i%pi%p 对应,所以求出方程的解集即可。

考虑怎么解模 p 的不等式 :

0<=x+delta<=p-1 <=> -delta<=x<=p-1-delta <=> [l,r] (l<=r) 或 [0,r],[l,n-1] (l>r)

注意要把两边转成非负数,并且分类讨论。(这个当成结论记,毕竟没有严格证明)。

最后维护求交即可。

#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define ll long long #define PII pair<ll,int> #define All(a) a.begin(),a.end() using namespace std; const int mx=4e6+5; struct node{ int l,r; bool operator <(const node &a)const { return l<a.l||l==a.l&&r<a.r; } }t[mx]; int n,a,b,p,m,tot; char op[mx]; int main() { scanf("%d%d%d%d%d",&n,&a,&b,&p,&m); scanf("%s",op); //这个模数解方程很恶心 for(int i=0,j=0;i<m;i++) { int delta=(1ll*i*a+b)%n; int x,y; //结论是反的 if(op[i]=='1') { //0<=x+delta<=p-1 //-delta<=x<=p-1-delta x=(-delta+n)%n; y=(p-1-delta+n)%n; } else { //p<=x+delta<=n-1 //p-delta<=x<=n-1-delta x=(p-delta+n)%n; y=(n-1-delta+n)%n; } //分类讨论解方程 if(x<=y) { t[++tot].l=x,t[tot].r=y; } else { t[++tot].l=0,t[tot].r=y,t[++tot].l=x,t[tot].r=n-1; } } //扫一遍 (n-m,n) for(int i=n-m+1;i<n;i++) { int x=1ll*a*i%n; t[++tot].l=x,t[tot].r=x; } //t[] 求并集: //1. 先按左端点排序,然后按右端点合并 sort(t+1,t+1+tot); // for(int i=1;i<=tot;i++) { // printf("%d %d\n",t[i].l,t[i].r); // } int l=t[1].l,r=t[1].r,tmp=0; //细节问题 //统计交集点的个数 for(int i=2;i<=tot;i++) { if(t[i].l<=r) r=max(r,t[i].r); else { tmp+=r-l+1; l=t[i].l,r=t[i].r; } } if(l<=r) { tmp+=r-l+1; } printf("%d",n-tmp); }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530308.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(17)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示