bzoj 2217 Lollipop

Posted jack_yyc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2217 Lollipop相关的知识,希望对你有一定的参考价值。

题目大意:

有一个长度为n的序列a1,a2,...,an。其中ai要么是1("W"),要么是2("T")

现在有m个询问,每个询问是询问有没有一个连续的子序列,满足其和为q

思路:

因为序列中只有1和2

所以一定存在一个前缀和等于x或x-1

当前缀和等于x直接输出即可

若等于x-1 则可以建一个r数组存储向后延伸有多少个连续的2

这样可以将这一段前缀和向后移

如果r 1较小 直接右移

否则向右移使右侧+1

具体可以手画来推

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 2001000
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch==-) f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-0;ch=getchar();}
18     return x*f;
19 }
20 int n,T,hsh[MAXN],s[MAXN],r[MAXN]; 
21 char ch[MAXN];
22 int main()
23 {
24     n=read(),T=read();scanf("%s",ch+1);
25     for(int i=1;i<=n;i++) s[i]=s[i-1]+((ch[i]==W)?1:2),hsh[s[i]]=i;
26     int tmp=n+1,x,k;
27     for(int i=n;i;i--) {if(ch[i]==W) tmp=i,k=i;r[i]=tmp-i;}
28     while(T--)
29     {
30         x=read();
31         if(x==1) printf("%d %d\n",k,k);
32         else if(hsh[x]) printf("%d %d\n",1,hsh[x]);
33         else if(hsh[x-1])
34         {
35             if(r[hsh[x-1]+1]>r[1]) printf("%d %d\n",2+r[1],hsh[x-1]+r[1]+1);
36             else if(r[hsh[x-1]+1]+hsh[x-1]+1<=n) printf("%d %d\n",1+r[hsh[x-1]+1],hsh[x-1]+r[hsh[x-1]+1]+1);
37             else puts("NIE");
38         }
39         else puts("NIE");
40     }
41 }
View Code

网上的大佬好像都是用的前缀和x+1 大概会方便一些?

以上是关于bzoj 2217 Lollipop的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 2217 Lollipop

POI2011 棒棒糖 Lollipop

以下代码片段 C++ 的说明

如何在带有 Android 5.0 Lollipop 的代码(不是 xml)中以编程方式使用 RippleDrawable?

Bzoj2339--Hnoi2011卡农

未执行活动转换 (Lollipop)