zoukankan      html  css  js  c++  java
  • P3514 [POI2011]LIZ-Lollipop(规律+瞎搞)

    题意

    给一个只有1和2的序列,每次询问有没有一个子串的和为x

    ( 1≤n,m≤1 000 000 )kkk ( 1≤k≤2 000 000 )

    题解

    我觉得是道好题。

    主要是证明一个性质:假如有一个字串的和为偶(奇)数,那么小于这个偶(奇)数的所有偶(奇)数一定等于这个串的某个字串的和。

    我们考虑这个串的边界l,r

    假设l==1,r==1那么l++,r--,和可以减2

    假设l==2,r==1那么l++,和可以减2;

    假设l==1,r==2那么r--,和可以减2;

    假设l==2,r==2那么l++或r--和可以减2;

    所以我们找到可以用一个串表示的最大偶(奇)数然后一直缩小这个区间就行。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=1000100;
     8 const int M=2000100;
     9 char s[M];
    10 int n,m,a[N],sum,head,tail,l,r,ll[M],rl[M];
    11 int main(){
    12     scanf("%d%d",&n,&m);
    13     cin>>s; 
    14     int len=strlen(s);
    15     for(int i=0;i<len;i++){
    16         if(s[i]=='W')a[i+1]=1;
    17         else a[i+1]=2;
    18     }
    19     for(int i=1;i<=n;i++)
    20         sum+=a[i];
    21     head=1;
    22     tail=n;
    23     while(a[head]!=1&&head<=n)head++;
    24     head++;
    25     while(a[tail]!=1&&tail>=1)tail--;
    26     tail--;
    27     l=1;r=n;
    28     while(l<=r){
    29     //    cout<<sum<<" "<<l<<" "<<r<<endl;
    30         rl[sum]=r;ll[sum]=l;
    31         if(a[l]==1&&a[r]==1){
    32             l++;r--;sum-=2;
    33         }
    34         else if(a[l]==2){
    35             l++;sum-=2;
    36         }
    37         else{
    38             r--;
    39             sum-=2;
    40         }
    41     }
    42     sum=0;
    43     if(head<=n||tail>=1){
    44         if(head-1<n-tail){
    45             l=head;
    46             r=n;
    47             for(int i=head;i<=n;i++)
    48                 sum+=a[i];
    49         }
    50         else{
    51             l=1;r=tail;
    52             for(int i=1;i<=tail;i++)
    53                 sum+=a[i];
    54         }
    55     //    cout<<sum<<endl;
    56         while(l<=r){
    57             rl[sum]=r;ll[sum]=l;
    58             if(a[l]==1&&a[r]==1){
    59                 l++;r--;sum-=2;
    60             }
    61             else if(a[l]==2){
    62                 l++;sum-=2;
    63             }
    64             else{
    65                 r--;
    66                 sum-=2;
    67             }
    68         }
    69     }
    70     for(int i=1;i<=m;i++){
    71         int k;
    72         scanf("%d",&k);
    73         if(ll[k]==0&&rl[k]==0)printf("NIE
    ");
    74         else printf("%d %d
    ",ll[k],rl[k]);
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    2017-2018-1 20155232 嵌入式C语言——时钟
    实践——ELF文件格式分析
    实践——程序破解
    实践——模块
    《Linux内核分析》期终总结
    《Linux内核分析》第八周:进程的切换和系统的一般执行过程
    《Linux内核设计与实现》读书笔记六
    《深入理解计算机系统》读书笔记五
    《Linux内核分析》第七周: 可执行程序的装载
    《Linux内核设计与实现》读书笔记四
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9447147.html
Copyright © 2011-2022 走看看