zoukankan      html  css  js  c++  java
  • [20200728NOIP提高组模拟T2]愉快的logo设计

    题目大意:

      今有一数,名之曰$k$,范围一至十也.先用此数构造字符串$s(k)$,$s(0)$为'J''O''I'三个字符选其一单独构成字符,此后$s(k)$为$4^{k-1}$个$J$,$4^{k-1}$个$O$,$4^{k-1}$个$I$与$s(k-1)$组成的字符串环.现给你一长度为$4^{k}$的模式串,请你求出最小的不同部分.

    solution:

      此题对于前$40%$数据,我们可以一一枚举起点进行匹配,复杂度$O((4^{k})^{2})$,但注意到有大量的重复且字符类型较少,于是我们可以预处理出前缀和,然后一一枚举进行计算即可,复杂度$O(3k cdot 4^{k})$

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define R register
    #define next kdjadskfj
    #define debug pust("mlg")
    using namespace std;
    typedef int ll;
    typedef long double ld;
    typedef unsigned long long ull;
    inline ll read();
    inline void write(ll x);
    inline void writeln(ll x);
    inline void writesp(ll x);
    ll k; 
    char wn[3000000];
    ll sum[3000000][4];
    ll ans;
    int main(){
        freopen("logo.in","r",stdin);
        freopen("logo.out","w",stdout);
        k=read();ans=1370120724;
        while(wn[1]!='J'&&wn[1]!='O'&&wn[1]!='I') wn[1]=wn[(1<<(k<<1))+1]=getchar();
        for(R ll i=2;i<=(1<<(k<<1));i++){
            wn[i]=wn[i+(1<<(k<<1))]=getchar();
        }
        for(R ll i=1;i<=((1<<(k<<1))<<1);i++){
            sum[i][0]=sum[i-1][0]+(wn[i]=='J');
            sum[i][1]=sum[i-1][1]+(wn[i]=='O');
            sum[i][2]=sum[i-1][2]+(wn[i]=='I');
        }
        for(R ll s=1;s<=(1<<(k<<1));s++){
            ll Tot=0,begin=s;
            for(R ll i=k-1;i>=0;i--){
                Tot+=sum[begin+(1<<(i<<1))-1][1]-sum[begin-1][1]+sum[begin+(1<<(i<<1))-1][2]-sum[begin-1][2];
                begin+=(1<<(i<<1));
                Tot+=sum[begin+(1<<(i<<1))-1][0]-sum[begin-1][0]+sum[begin+(1<<(i<<1))-1][2]-sum[begin-1][2];
                begin+=(1<<(i<<1));
                Tot+=sum[begin+(1<<(i<<1))-1][0]-sum[begin-1][0]+sum[begin+(1<<(i<<1))-1][1]-sum[begin-1][1];
                begin+=(1<<(i<<1));
            }
            ans=min(ans,Tot);
        }
        writeln(ans);
    }
    inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
    inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
    inline void writesp(ll x){write(x);putchar(' ');}
    inline void writeln(ll x){write(x);putchar('
    ');}

     

  • 相关阅读:
    1052 卖个萌 (20 分)
    1046 划拳 (15 分)
    1051 复数乘法 (15 分)
    1042 字符统计 (20 分)哈希
    1041 考试座位号 (15 分)哈希
    1061 判断题 (15 分)
    1093 字符串A+B (20 分)简单哈希
    Hibernate框架
    SVN的安装与介绍
    easyUI的简单操作
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13391220.html
Copyright © 2011-2022 走看看