【BZOJ】【P1361】【Wc2004】【孪生项链】【题解】【Lyndon Word+构造】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1361

wc的题目真是个个都是神题啊

首先看任务2

显然我们求出来循环节长度为k的串的个数然后除以n就好了

循环节长度为k的串 => 2^k-循环节长度不为k的串

循环节一定是k的约数

用f[k]表示循环节为k且仅为k的串的个数

那么


高精递推即可

任务1

神奇的构造

直接把题解贴上吧


首先我们把给定串复制无限份依次写下来,形成一个以原串为循环节的长度无限的串,然后截取前n位,再把这个串看成一个二进制数做加1运算,在消去末尾所有的0,最后得到的即为所求的后继项链。

证明:

 设原项链为s,我们所得到的新串为t,我们将t中出现的每一个原项链s成为t的一个小节,t最后的所剩部分也称作一个小节。我们将分以下两步证明算法的正确性

1.新串t是一个合法的项链,且大于s。

2.不存在另一个大于原项链s的项链小于t。

3. 

证明1:首先,很容易证明t的最后一个小节是大于t的任何一个其他的小节的。接下来我们考察新串t的任一种循环表示t’,如果t’的起始位置是在t的某一个小节的第一位,那么将t与t’比较,它们的前几个小节都是相同的,直至比较至t’的最后一个小节,它一定是大于t所对应的小节的,故t’>t。如果t’的起始位置不是在t的某一个小节的第一位,设原串s的长度为m,则t’的前m位一定是s的一种循环表示,由于s是一个合法项链,即t’的前m位一定大于s,即大于t的前m位,即t’>t。也就是说,对于t的任一个循环表示t’,都有t’>t,故t没有循环节,且它是所有循环表示中最小的一个,即t也是一个合法的项链。而在由s构造t的过程中,每一步都是增大超作,故最后得到的串t也是大于s的。

证明2:假设存在另一个项链r使得s<r<t,由于r<t,必然存在一个位置使得在这个位置上r中的数字是0而t中的是1,设这个位置是在t的第p个小节中,则对于这个小节,有r<t。考察r的以这个小节的第一位为初始位置的循环表示r’,我们发现r’<s,而r<r’,故r<s,与假设矛盾。故不存在这样的项链r,原命题成立。


Code:

(不会写高精只会用python我是不是废了)

import math
import sys
n,m,k=[int(x) for x in raw_input().split()]
f=[0]*1001
f[1]=2
for i in range(2,k+1):
    f[i]=2**i
    for j in range(1,int(math.sqrt(i))+1):
        if i%j==0:
            f[i]-=f[j]
            if j*j!=i and j!=1:
                f[i]-=f[i/j]
print f[k]/k
s=raw_input()
st=s
while len(s)<n:
    s=s+st
s=s[0:n]
ps=0
for i in range(len(s)-1,-1,-1):
    if s[i]=='0':
        ps=i
        break
print str(s[0:ps])+'1'




你可能感兴趣的:(bzoj)