• [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('
    ');}

     

  • 相关阅读:
    网页打开速度的心理学
    UML建模——用例图(Use Case Diagram)
    漫谈干系人识别管理
    干系人分析的3个方法:除了目标用户还要考虑谁?
    计算机网络-复习笔记
    项目经理必掌握的国际项目管理知识体系结构及内容
    剑指Offer面试题:5.重建二叉树
    剑指Offer面试题:4.从尾到头打印链表
    剑指Offer面试题:3.替换空格
    剑指Offer面试题:2.二维数组中的查找
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13391220.html
Copyright © 2020-2023  润新知