P3514 [POI2011]LIZ-Lollipop(规律+瞎搞)

题意

给一个只有1和2的序列,每次询问有没有一个子串的和为xios

( 1≤n,m≤1 000 000 )kkk ( 1≤k≤2 000 000 )spa

题解

我以为是道好题。code

主要是证实一个性质:假若有一个字串的和为偶(奇)数,那么小于这个偶(奇)数的全部偶(奇)数必定等于这个串的某个字串的和。blog

咱们考虑这个串的边界l,rci

假设l==1,r==1那么l++,r--,和能够减2string

假设l==2,r==1那么l++,和能够减2;it

假设l==1,r==2那么r--,和能够减2;io

假设l==2,r==2那么l++或r--和能够减2;class

因此咱们找到能够用一个串表示的最大偶(奇)数而后一直缩小这个区间就行。stream

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<algorithm>
 6 using namespace std;  7 const int N=1000100;  8 const int M=2000100;  9 char s[M]; 10 int n,m,a[N],sum,head,tail,l,r,ll[M],rl[M]; 11 int main(){ 12     scanf("%d%d",&n,&m); 13     cin>>s; 14     int len=strlen(s); 15     for(int i=0;i<len;i++){ 16         if(s[i]=='W')a[i+1]=1; 17         else a[i+1]=2; 18  } 19     for(int i=1;i<=n;i++) 20         sum+=a[i]; 21     head=1; 22     tail=n; 23     while(a[head]!=1&&head<=n)head++; 24     head++; 25     while(a[tail]!=1&&tail>=1)tail--; 26     tail--; 27     l=1;r=n; 28     while(l<=r){ 29     // cout<<sum<<" "<<l<<" "<<r<<endl;
30         rl[sum]=r;ll[sum]=l; 31         if(a[l]==1&&a[r]==1){ 32             l++;r--;sum-=2; 33  } 34         else if(a[l]==2){ 35             l++;sum-=2; 36  } 37         else{ 38             r--; 39             sum-=2; 40  } 41  } 42     sum=0; 43     if(head<=n||tail>=1){ 44         if(head-1<n-tail){ 45             l=head; 46             r=n; 47             for(int i=head;i<=n;i++) 48                 sum+=a[i]; 49  } 50         else{ 51             l=1;r=tail; 52             for(int i=1;i<=tail;i++) 53                 sum+=a[i]; 54  } 55     // cout<<sum<<endl;
56         while(l<=r){ 57             rl[sum]=r;ll[sum]=l; 58             if(a[l]==1&&a[r]==1){ 59                 l++;r--;sum-=2; 60  } 61             else if(a[l]==2){ 62                 l++;sum-=2; 63  } 64             else{ 65                 r--; 66                 sum-=2; 67  } 68  } 69  } 70     for(int i=1;i<=m;i++){ 71         int k; 72         scanf("%d",&k); 73         if(ll[k]==0&&rl[k]==0)printf("NIE\n"); 74         else printf("%d %d\n",ll[k],rl[k]); 75  } 76     return 0; 77 }
相关文章
相关标签/搜索