zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    二分图匹配初步
    动态规划初步
    一些排日程的经典方法
    petri网初步
    笔记:美国院士教你写论文
    Ubuntu18.04彻底删除MySQL数据库
    ubuntu18.04 安装 wps2019
    ubuntu18.04 阿里镜像源
    Ubuntu 18.04 使用标准Ubuntu 仓库进行自动化安装NVIDIA驱动
    linux maven环境变量配置
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8486673.html
Copyright © 2011-2022 走看看