zoukankan      html  css  js  c++  java
  • 【洛谷3526】[POI2011] OKR-Periodicity(border)

    点此看题面

    • 给定一个长度为(n)的字符串,求长度为(n)的字典序最小的(01)串,满足它们的周期集合相同。
    • 数据组数(le20)(nle2 imes10^5)

    (border)性质

    众所周知,一个长度为(n)的字符串有长度为(k)的周期等价于有长度为(n-k)(border)

    所以我们先利用(KMP)求出这个字符串的(border)集合,那么问题就变成要构造一个(01)串与它的(border)集合相同。

    首先考虑如何构造长度最小的那个(border)(设为(p_{min})),若(p_{min}=1)就是一个( exttt{"0"}),否则是(p_{min}-1)( exttt{"0"})后面跟上一个( exttt{"1"})

    然后考虑如何从(p_{lst})(p_{now})扩展答案,分类讨论:

    • 如果(2p_{lst}ge p_{now}),直接把原本答案串的最后(p_{now}-p_{lst})个字符复制一份即可。
    • 如果(2p_{lst}<p_{now}),最好的情况当然是首尾填(p_{lst}),中间放(p_{now}-2p_{lst})( exttt{"0"}),但这样可能会产生不应存在的周期。发现(p_{lst}+(p_{now}-2p_{lst}) imes exttt{"0"}+p_{lst})有不应存在的周期等价于(p_{lst}+(p_{now}-2p_{lst}) imes exttt{"0"})有长度为(m=p_{now}-p_{lst})约数的周期,也就是说(m-nxt_m)(m)的约数。此时,只要把最后一个( exttt{"0"})改成( exttt{"1"})即可。

    我们只要实时维护好答案串的(nxt)数组即可。

    代码:(O(Tn))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Rg register
    #define RI Rg int
    #define Cn const
    #define CI Cn int&
    #define I inline
    #define W while
    #define N 200000
    using namespace std;
    int n,p[N+5];char s[N+5];
    int m,nxt[N+5];char g[N+5];I void A(Cn char& x)//在末尾添加一个字符
    {
    	if(g[++m]=x,m==1) return;RI i=nxt[m-1];W(i&&g[i+1]^x) i=nxt[i];nxt[m]=i+(g[i+1]==x);//求nxt
    }
    int main()
    {
    	RI Tt,i,t;scanf("%d",&Tt);W(Tt--)
    	{
    		for(scanf("%s",s+1),n=strlen(s+1),m=0,i=1;i<=n;++i) A(s[i]);for(t=0,i=n;i;i=nxt[i]) p[++t]=i;//求出原串所有border
    		if(m=0,p[t]^1) {for(i=1;i^p[t];++i) A('0');A('1');}else A('0');W(--t)//求出初始答案串
    		{
    			if(2*p[t+1]>=p[t]) {for(i=p[t+1]-(p[t]-p[t+1])+1;i<=p[t+1];++i) A(g[i]);continue;}//直接把最后p[t]-p[t+1]个字符复制一份
    			for(i=1;i<=p[t]-2*p[t+1];++i) A('0');!(m%(m-nxt[m]))&&(--m,A('1'),0);for(i=1;i<=p[t+1];++i) A(g[i]);//检验能否在中间放p[t]-2*p[t+1]个0,不行则把最后的0改成1
    		}g[n+1]=0,puts(g+1);
    	}return 0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    计算tableview的高度
    UIcollectionview与tableview的区别
    ios 屏幕适配
    避免表单多次提交
    Action权限验证
    正则小记
    在OnActionExecuting中阻止后面Action的执行
    批量上传图片uplodify插件
    表单多次提交
    windows 下安装 rabbitmq报init terminating in do_boot错误
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu3526.html
Copyright © 2011-2022 走看看