zoukankan      html  css  js  c++  java
  • bzoj 4974 [Lydsy八月月赛]字符串大师

    题目大意:

    一个串T是S的循环节 当且仅当存在正整数k 使得S是T重复k次的前缀 比如abcd是abcdabcdab的循环节

    给定一个长度为n的仅由小写字符构成的字符串S 请对于每个k(1<=k<=n) 求出S长度为k的前缀的最短循环节的长度per_i

    已知per_1,per_2,...,per_n 请找到一个长度为n的小写字符串S 使得S能对应上per

    思路:

    若一个per i!=i 直接模一下在之前的里面找就行了

    若不是 找到一些之前循环中出现的字符,这些字符如果出现在这一位会导致循环per改变

    仿照next数组的思路 找出来 加上字典序最小的一个可用字符

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<cstring>
     7 #include<queue>
     8 #include<map>
     9 #include<vector>
    10 #define ll long long
    11 #define inf 2147483611
    12 #define MAXN 1000100
    13 #define MOD 1000000
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 int n,a[MAXN],cnt,hsh[30],j;
    23 char ans[MAXN];
    24 int main()
    25 {
    26     n=read();
    27     for(int i=1;i<=n;i++) a[i]=read();
    28     ans[1]='a';
    29     for(int i=2;i<=n;i++)
    30     {
    31         if(a[i]!=i) {ans[i]=ans[((i-1)%a[i])+1];continue;}
    32         cnt++;
    33         j=i-1;
    34         while(a[j]!=j)
    35         {
    36             j=(j-1)%a[j]+1;
    37             hsh[ans[j+1]-'a']=cnt;
    38         }
    39         for(int k=1;k<=26;k++) if(hsh[k]!=cnt) {ans[i]=(char) 'a'+k;break;}
    40     }
    41     for(int i=1;i<=n;i++) printf("%c",ans[i]);
    42 }
    View Code
  • 相关阅读:
    CMake 3.8.2 Online Manuals
    如何查找UDID
    产品经理那些事儿学习整理笔记
    IOS KVO与NSNotificationCenter简单使用
    整理分享内容
    iOS解决两个静态库的冲突 duplicate symbol
    IOS 添加libMobileVLCKit .a到项目中编译问题
    OpenERP为form和tree视图同时指定view_id的方法
    openerp related字段解读
    openerp图片路径处理
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7813975.html
Copyright © 2011-2022 走看看