构造——[POI2011]LIZ-Lollipop

题解:

思维+构造+…
言归正传,这道题求一个价值为k的区间,很容易想到要使用前缀和的方式,当我们值刚等于这个值的时候直接输出就好了,否则我们就需要进行移动区间端点,我们可以知道如果相邻区间相差为1的话那么我们可以很容易平移几次端点就得到,所以我们分析题目知道我们可能产生这样些二元组(1,1),(1,2),(2,2),(2,1)。所以只有(2,2)是相差为2的,所以我们记录当前位置有多少个连续的2,然后分情况讨论。构造sum-1的情况。这样的话我们就可以预处理出所以sum的区间了。

#include 
using namespace std;
const int N=1e6+10;
int sum[N],l[N],r[N];
char a[N];
signed main()
{
    int n,q; scanf("%d%d",&n,&q);
    scanf("%s",a+1);
    for(int i=n;i;i--){
        if(a[i]=='T') sum[i]=sum[i+1]+1;
        else sum[i]=0;
    }
    int res=0;
    for(int i=1;i<=n;i++){
        res+=a[i]=='T'?2:1;
        l[res]=1,r[res]=i;
        if(a[i]=='T'){
            if(sum[1]<sum[i]) l[res-1]=2+sum[1],r[res-1]=i+sum[1];
            else l[res-1]=1+sum[i],r[res-1]=i+sum[i];
        }
    }
    while(q--){
        int ask; scanf("%d",&ask);
        if(l[ask]>=1&&r[ask]<=n) printf("%d %d\n",l[ask],r[ask]);
        else printf("NIE\n");
    }
}

你可能感兴趣的:(思维,构造)