BZOJ 2217: [Poi2011]Lollipop

题目在这里呀!
离NOIP就一周了喵 但感觉好累好傻什么都想不出来了 ,越听课越傻吗qwq
博客也是一段时间没写了qaq(顺便乱入庆祝IG夺冠!金色的雨诶!!)

题意

很清楚了吧emmm

题解

首先对于一段区间的和为sum,那么sum-2一定可行。(好像并没怎么用到
现在我们要知道对于一个前缀和sum,如何拼出sum-1。
s i s_i si为从i开始连续T的个数。
1、如果 s 1 < = s i s_1<=s_i s1<=si那么去掉前 s 1 s_1 s1个T再加上第 s 1 + 1 s_1+1 s1+1位上的W,在后面加上 s 1 s_1 s1个T即可拼出sum-1,所以 l = 1 + s 1 + 1 , r = i + s 1 l=1+s_1+1,r=i+s_1 l=1+s1+1,r=i+s1
2、如果 s 1 > s i s_1>s_i s1>si同样的道理得出 l = 1 + s i , r = i + s i l=1+s_i,r=i+s_i l=1+si,r=i+si
最后输出答案即可?

//Suplex
#include 
#include 
#include 
#include 
#include 
#define N 1001000
using namespace std;
int n,m,a[N],s[N],l[N+N],r[N+N],sum;
char st[N];

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}

int main()
{
    n=read();m=read();
    scanf("%s",st+1);
    for(int i=1;i<=n;i++) a[i]=(st[i]=='W'?1:2);
    for(int i=n;i;i--){s[i]=s[i+1]+1;if(a[i]==1) s[i]=0;}
    sum=0;
    for(int i=1;i<=n;i++){
        sum+=a[i];
        l[sum]=1;r[sum]=i;
        if(a[i]==2){
            if(s[1]<s[i]) l[sum-1]=1+s[1]+1,r[sum-1]=i+s[1];
            else if(i+s[i]<=n) l[sum-1]=1+s[i],r[sum-1]=i+s[i];
        }
    }
    while(m--){
        int x=read();
        if(x>sum || !l[x]) puts("NIE");
        else printf("%d %d\n",l[x],r[x]);
    }
    return 0;
}

你可能感兴趣的:(BZOJ,OI,贪心)