BZOJ 2217 Poi2011 Lollipop

题目大意:给定一个由1和2组成的序列,多次询问是否存在一个区间满足区间和=x

如果x>sum显然无解

如果存在一个前缀和为x则直接输出

否则一定存在一个前缀和[1,i]等于x+1

然后我们将左右端点同时右移 显然如果某一时刻a[l]=1或者a[r+1]=1那么我们就找到解了

记录exti表示从i开始有多少个连续的2

如果ext1<exti,那么解为[1+ext1+1,i+ext1]

如果ext1≥exti且i+exti≠n+1,那么解为[1+exti,i+exti]

否则无解

O(n)预处理所有答案即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 2002002
using namespace std;
int n,m,sum;
char s[M>>1];
int ext[M],l[M],r[M];
int main()
{
    int i,x;
    cin>>n>>m;
    scanf("%s",s+1);
    for(i=n;i;i--)
    {
        ext[i]=ext[i+1]+1;
        if(s[i]==‘W‘)
            ext[i]=0;
    }
    for(i=1;i<=n;i++)
    {
        sum+=s[i]==‘W‘?1:2;
        l[sum]=1;r[sum]=i;
        if(s[i]==‘T‘)
        {
            if(ext[1]<ext[i])
                l[sum-1]=ext[1]+2,r[sum-1]=i+ext[1];
            else if(i+ext[i]!=n+1)
                l[sum-1]=1+ext[i],r[sum-1]=i+ext[i];
        }
    }
    for(i=1;i<=m;i++)
    {
        scanf("%d",&x);
        if( x>sum || !l[x] )
            puts("NIE");
        else
            printf("%d %d\n",l[x],r[x]);
    }
    return 0;
}
时间: 2024-10-07 02:46:30

BZOJ 2217 Poi2011 Lollipop的相关文章

【BZOJ2217】[Poi2011]Lollipop 乱搞

[BZOJ2217][Poi2011]Lollipop 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) Out

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<iostrea

[BZOJ 2350] [Poi2011] Party 【Special】

题目链接: BZOJ - 2350 题目分析 因为存在一个 2/3 n 大小的团,所以不在这个团中的点最多 1/3 n 个. 牺牲一些团内的点,每次让一个团内的点与一个不在团内的点抵消删除,最多牺牲 1/3 n 个团内的点,至少剩余一个 1/3 n 的团. 如果两个点之间没有边,那么至少有一个点在团外,删掉这两个点! 代码 #include <iostream> #include <cstdlib> #include <cstring> #include <cst

[BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换左右子树无关,是否交换左右子树取决于交换后 “跨越 x 左子树与右子树的逆序对” 是否会减小. 因此我们要求出两种情况下的逆序对数,使用线段树合并,对每个节点建一棵线段树,然后合并的同时就求出两种情况下的逆序对. 代码 #include <iostream> #include <cstdli

[BZOJ] 2276: [Poi2011]Temperature

2276: [Poi2011]Temperature Time Limit: 20 Sec  Memory Limit: 32 MBSubmit: 731  Solved: 334[Submit][Status][Discuss] Description The Byteotian Institute of Meteorology (BIM) measures the air temperature daily. The measurement is done automatically, an

BZOJ 2525 [Poi2011]Dynamite 二分+树形贪心

题意: n个点,一棵树,有些点是关键点,可以将m个点染色. 求所有关键点到最近的被染色点的距离的最大值最小. 解析: 反正从这道题我是学了一种做题思路? 大爷讲课的时候说的:一般选择某些点的代价相同的话都是贪心,代价不同的话一般都是DP. 想想也挺对的,不过就是没有感悟到过? 反正这题考试的时候我是直接D了贪心的- -! 忘了为啥D了. 显然最大值最小我们需要二分一下这个值. 然后接下来我们从下往上扫整棵树. 节点的状态有几个? 第一种是 子树内没有不被覆盖的关键点,并且子树中有一个节点的贡献可

BZOJ 2280 Poi2011 Plot 二分答案+随机增量法

题目大意:给定n个点,要求分成m段,使每段最小覆盖圆半径的最大值最小 二分答案,然后验证的时候把点一个个塞进最小覆盖圆中,若半径超了就分成一块-- 等等你在跟我说不随机化的随机增量法? 好吧 那么对于一个点pos,我们要计算最大的bound满足[pos,bound]区间内的最小覆盖圆半径不超过二分的值 直接上二分是不可取的,因为我们要求m次,如果每次都验证一遍[1,n/2]直接就炸了 我们可以这么搞 首先判断[pos,pos+1-1]是否满足要求 然后判断[pos,pos+2-1]是否满足要求

bzoj 2276: [Poi2011]Temperature——单调队列

Description 某国进行了连续n天的温度测量,测量存在误差,测量结果是第i天温度在[l_i,r_i]范围内. 求最长的连续的一段,满足该段内可能温度不降 第一行n 下面n行,每行l_i,r_i 1<=n<=1000000 一行,表示该段的长度 Sample Input 6 6 10 1 5 4 8 2 5 6 8 3 5 Sample Output 4 ------------------------------------ 这道题其实就是维护一个连续的不下降序列 考虑维护一个队列 对

BZOJ 2527 [Poi2011]Meteors(整体二分)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2527 [题目大意] 有N个成员国.现在它发现了一颗新的星球, 这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况. BIU的第i个成员国希望能够收集Pi单位的陨石样本. 你的任务是判断对于每个国家,它需要在第几次陨石雨之后,才能收集足够的陨石. [题解] 如果枚举每场陨石雨,树状数组查询每个