BZOJ4377: [POI2015]Kurs szybkiego czytania

来源:互联网 发布:数据采集卡和plc对比 编辑:程序博客网 时间:2024/05/22 06:15

学到了求区间交并的姿势..

注意到a,n互质,所以对于所有的0<=i< n,ai+b mod n互不相同,一一对应
我们令s=ai+b,问大串包含多少个小串,就是问有多少个s使得s,s+a,s+2a,s+3a…..满足限制
于是我们可以列出若干个形如l<=s< r(Mod n)的限制
这些不等式解集的交就是能取的s的数量,减掉尾部的m-1个i就是答案(后缀不足m不能作为开头)
卡常卡了好久qwq

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define inf 1e9using namespace std;const int maxm = 1000010;int n,A,B,p,m;char str[maxm];struct node{    int x,c;    node(){}    node(const int _x,const int _c){x=_x;c=_c;}}a[maxm<<2]; int len;int t[maxm<<1],tp;inline bool cmp(const node x,const node y){ return x.x<y.x; }int main(){    scanf("%d%d%d%d%d",&n,&A,&B,&p,&m);    scanf("%s",str);    for(int i=0,k=0;i<m;i++,k+=A)    {        if(k>=n) k-=n;        int l,r;        if(str[i]=='0') l=0,r=p-1;        else l=p,r=n-1;        l-=k; if(l<0) l+=n;        r-=k; if(r<0) r+=n;        if(l<=r)        {            r++;            a[++len]=node(l,1);            if(r<n) a[++len]=node(r,-1);        }        else        {            a[++len]=node(0,1);            a[++len]=node(r+1,-1);            a[++len]=node(l,1);        }    }    for(int i=n-m+1,k=((ll)A*i+(ll)B)%n;i<n;i++,k+=A)    {        if(k>=n) k-=n;        t[++tp]=k;    }    sort(a+1,a+len+1,cmp);    sort(t+1,t+tp+1);    int c=0,ans=0;    int pos=1;    for(int i=1;i<=len;)    {        int j; int tc=c;        for(j=i;j<=len&&a[j].x==a[i].x;j++) c+=a[j].c;        int temp=0; while(t[pos]<a[i].x&&pos<=tp) pos++,temp++;        if(tc==m) ans+=a[i].x-a[i-1].x-temp;        i=j;    }    int temp=0; while(t[pos]<n&&pos<=tp) pos++,temp++;    if(c==m) ans+=n-a[len].x-temp;    printf("%d\n",ans);    return 0;}
原创粉丝点击