zoukankan      html  css  js  c++  java
  • [POI2011]LIZ-Lollipop(前缀和)

    原题

    题面

    Solution

    我是不会告诉你我一开始写了一个二分答案+rand的算法的。。。
    这样子你可以获得80分的好成绩!!!

    #pragma GCC diagnostic error "-std=c++11"
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("inline")
    #pragma GCC optimize("-fgcse")
    #pragma GCC optimize("-fgcse-lm")
    #pragma GCC optimize("-fipa-sra")
    #pragma GCC optimize("-ftree-pre")
    #pragma GCC optimize("-ftree-vrp")
    #pragma GCC optimize("-fpeephole2")
    #pragma GCC optimize("-ffast-math")
    #pragma GCC optimize("-fsched-spec")
    #pragma GCC optimize("unroll-loops")
    #pragma GCC optimize("-falign-jumps")
    #pragma GCC optimize("-falign-loops")
    #pragma GCC optimize("-falign-labels")
    #pragma GCC optimize("-fdevirtualize")
    #pragma GCC optimize("-fcaller-saves")
    #pragma GCC optimize("-fcrossjumping")
    #pragma GCC optimize("-fthread-jumps")
    #pragma GCC optimize("-funroll-loops")
    #pragma GCC optimize("-fwhole-program")
    #pragma GCC optimize("-freorder-blocks")
    #pragma GCC optimize("-fschedule-insns")
    #pragma GCC optimize("inline-functions")
    #pragma GCC optimize("-ftree-tail-merge")
    #pragma GCC optimize("-fschedule-insns2")
    #pragma GCC optimize("-fstrict-aliasing")
    #pragma GCC optimize("-fstrict-overflow")
    #pragma GCC optimize("-falign-functions")
    #pragma GCC optimize("-fcse-skip-blocks")
    #pragma GCC optimize("-fcse-follow-jumps")
    #pragma GCC optimize("-fsched-interblock")
    #pragma GCC optimize("-fpartial-inlining")
    #pragma GCC optimize("no-stack-protector")
    #pragma GCC optimize("-freorder-functions")
    #pragma GCC optimize("-findirect-inlining")
    #pragma GCC optimize("-fhoist-adjacent-loads")
    #pragma GCC optimize("-frerun-cse-after-loop")
    #pragma GCC optimize("inline-small-functions")
    #pragma GCC optimize("-finline-small-functions")
    #pragma GCC optimize("-ftree-switch-conversion")
    #pragma GCC optimize("-foptimize-sibling-calls")
    #pragma GCC optimize("-fexpensive-optimizations")
    #pragma GCC optimize("-funsafe-loop-optimizations")
    #pragma GCC optimize("inline-functions-called-once")
    #pragma GCC optimize("-fdelete-null-pointer-checks")
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #define ll long long
    #define file(a) freopen(a".in","r",stdin)//;freopen(a".out","w",stdout)
    using namespace std;
    inline int gi(){
        int sum=0,f=1;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-f;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return f*sum;
    }
    inline ll gl(){
        ll sum=0,f=1;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-f;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return f*sum;
    }
    int a[2000010],sum[2000010];
    struct node{
        int id,val;
        bool operator<(const node b)const{
            return val<b.val;
        }
    }d[2000010];
    int main(){
        srand(time(NULL));
    #ifndef ONLINE_JUDGE
        file("example");
    #endif
        int i,j,n,m,k;
        n=gi();m=gi();
        for(i=1;i<=n;i++){
            char ch=getchar();
            a[i]=ch=='W'?1:2;
        }
        for(i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
        for(i=1;i<=n;i++){
            d[i]=(node){i,rand()};
        }
        sort(d+1,d+n+1);
        while(m--){
            k=gi();int flag=0;
            for(int x=1;x<=n;x++){
                i=d[x].id;
                int l=i,r=n,ans=0;
                while(l<=r){
                    int mid=(l+r)>>1;
                    if(sum[mid]-sum[i-1]>k)r=mid-1;
                    else if(sum[mid]-sum[i-1]<k)l=mid+1;
                    else{ans=mid;break;}
                }
                if(ans){
                    printf("%d %d
    ",i,ans);flag=1;
                    break;
                }
            }
            if(!flag)puts("NIE");
        }
        return 0;
    }
    

    这是一道比较有思维难度的题目,我们考虑一下如果一段区间有1,那么显然都可以完成对吧。
    这里给一个比较简单的证明:
    (Sum)表示前i个数的和,(sum_i)表示i往后有多少个T.我们考虑当前这个数如果是T(2),那么有如下两种情况

    • i向后延续的长度>1向后延续的长度,则有:
      (Sum-1=a_{sum_1+2}+a_{sum_1+3}+...+a_{sum_1+i})

    这个可以这么想,我们把它差分一下,变成:
    (a_1+a_2+...+a_{sum_1+i}-a_1-a_2-...-a_{sum_1+1})
    因为(1~sum_1)都是2,所以前面的数都是2.
    然后我们考虑第一个式子(a_1+a_2+a_3+...+a_{sum_1+i})
    因为i向后延续的长度>1向后延续的长度,所以我们考虑把这i个数往前移,然后把1往后延续的长度放到后面,就有
    原式=(a_1+a_2+...+a_{sum_1+i}-a_1-a_2-a_{sum_1+1}=Sum-1)


    • 如果i延续的长度不能够到n,则有:
      (Sum-1=a_{sum_i+1}+a_{sum_i+2}+...+a_{sum_i+i})

    同理可证


    那么就可以写出下面这段代码了.

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #define ll long long
    #define file(a) freopen(a".in","r",stdin)//;freopen(a".out","w",stdout)
    using namespace std;
    inline int gi(){
        int sum=0,f=1;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-f;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return f*sum;
    }
    inline ll gl(){
        ll sum=0,f=1;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-f;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return f*sum;
    }
    int a[2000010],sum[2000010],Sum,l[2000010],r[2000010];
    int main(){
    #ifndef ONLINE_JUDGE
        file("example");
    #endif
        int i,j,n,m,k;
        n=gi();m=gi();
        for(i=1;i<=n;i++){
            char ch=getchar();
            if(ch=='T')a[i]=2;
            else a[i]=1;
        }
        for(i=n;i;i--)sum[i]=a[i]==2?(sum[i+1]+1):0;
        int Sum=0;
        for(i=1;i<=n;i++){
            Sum+=a[i];
            l[Sum]=1;r[Sum]=i;
            if(a[i]==2)
                if(sum[i]>sum[1])l[Sum-1]=sum[1]+2,r[Sum-1]=sum[1]+i;
                else if(sum[i]!=n-i+1)l[Sum-1]=sum[i]+1,r[Sum-1]=sum[i]+i;
        }
        while(m--){
            k=gi();
            if(l[k])printf("%d %d
    ",l[k],r[k]);
            else puts("NIE");
        }
        return 0;
    }
    
  • 相关阅读:
    MQTT服务器搭建--Mosquitto用户名密码配置
    linux下c语言获取当前时间
    Linux下用C获取当前时间
    iptraf:一个实用的TCP/UDP网络监控工具
    CentOS配制FTP服务器,并且能用root权限登录
    centos6.4搭建ftp服务器
    两台Linux主机互传文件可以使用SCP命令来实现
    Linux 技巧:让进程在后台可靠运行的几种方法
    Linux 下 c 语言 聊天软件
    RobotFrameWork(五)控制流之if语句——Run Keyword If
  • 原文地址:https://www.cnblogs.com/cjgjh/p/9807642.html
Copyright © 2011-2022 走看看