bzoj 2217 [Poi2011]Lollipop 乱搞 贪心

2217: [Poi2011]Lollipop

Time Limit: 15 Sec  Memory Limit: 64 MBSec  Special Judge
Submit: 383  Solved: 159
[Submit][Status][Discuss]

Description

有一个长度为n的序列a1,a2,...,an。其中ai要么是1("W"),要么是2("T")。
现在有m个询问,每个询问是询问有没有一个连续的子序列,满足其和为q。

Input

第一行n,m (1<=n,m<=1000000)
第二行这个序列,起始编号为1,终止编号为n
下面每行一个询问q,询问有没有一个连续的子序列,满足其和为q (1<=q<=2000000)

Output

对于每个询问,输出一行,如果有,输出这个序列的起点和终点(如果有多个输出任意一个);如果没有,输出“NIE”。

Sample Input

5 3
TWTWT
5
1
7

Sample Output

1 3
2 2
NIE

HINT

尚无SPJ,请不要提交

 

这题有一个性质,如果存在一个连续的序列和为k,那么在前缀和中一定存在k或者k+1

为什么?

可以证明,如果l-r和为k,那么后面部分,可以不断减去,前面部分不断加入,如果相差为2,那么后面部分减去一个1,或者2,使其

差<2就可以了,这样是保证了这个性质。

所以对于这道题,对于k判断前缀和十分有k,有的话直接输出,否则判断是否有k+1,如果有的话,就记录前面二的个数,后面哪个位置是1,

然后搞一搞就好了。

 1 #pragma GCC optimize(2)
 2 #pragma G++ optimize(2)
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<cstring>
 8 
 9 #define N 27
10 using namespace std;
11 inline int read()
12 {
13     int x=0,f=1;char ch=getchar();
14     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
15     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
16     return x*f;
17 }
18 
19 #define MAXN 1000010
20 #define MAXM 1010
21 #define INF 1000000000
22 #define MOD 1000000007
23 #define eps 1e-8
24 #define ll long long
25 
26 int n,m;
27 char a[MAXN];
28 int s[MAXN],nxt[MAXN];
29 int v[MAXN<<1];
30 int main()
31 {
32     int i,x;
33     scanf("%d%d%s",&n,&m,a+1);
34     for(i=1;i<=n;i++)
35     {
36         s[i]=s[i-1]+1+(a[i]=='T');
37         v[s[i]]=i;
38     }
39     x=n+1;
40     for(i=n;i;i--)
41     {
42         if(a[i]=='W')x=i;
43         nxt[i]=x-i;
44     }
45     while(m--)
46     {
47         scanf("%d",&x);
48         if(v[x])printf("%d %d
",1,v[x]);
49         else if(v[x+1])
50         {
51             int l=1,r=v[x+1];
52             if(nxt[l]<nxt[r])
53             {
54                 r+=nxt[l];
55                 l+=nxt[l]+1;
56                 printf("%d %d
",l,r);
57             }else if(r+nxt[r]<=n)
58             {
59                 l+=nxt[r];
60                 r+=nxt[r];
61                 printf("%d %d
",l,r);
62             }else printf("NIE
");
63         }else printf("NIE
");
64     }
65 }
原文地址:https://www.cnblogs.com/fengzhiyuan/p/8486673.html