http://www.elijahqi.win/archives/2776
Description
跳蚤国王要召开第二届内阁会议,所以把所有跳蚤都召集到了会议室。所有跳蚤在会议室的圆桌前坐成了一个圈,从1
1
到n
n
标号,每人的面前都有一盏明灯。
就在会议就要开始的时候,国王突然发现,并不是所有的灯都点亮了,有强迫症的他绝不会在有灯没有被点亮的时候开始会议。
现在国王要指定一些位置的跳蚤,他会报出这些跳蚤的序号,让他们把面前的灯改变状态。
可是这些跳蚤大臣并不想开会,虽然这些跳蚤必须按照国王的指令形式行事,但是他们会在国王下达指令之后,偷偷转动面前的桌子任意次(转动一次之后本来在n
n
号跳蚤面前的灯就在1
1
号跳蚤面前了),这样虽然对应序列的跳蚤确实改变了面前的灯的状态,但是会议并不能开始因为灯还没有全部点亮。
国王也知道这一点,所以他很好奇,他有没有一种办法在有限轮之后开始会议呢?
小w向国王毛遂自荐,国王很怀疑小w的能力,所以为了保证数据强度,国王会给小w一个初始的串,每次问小w一个子串是否能在有限轮之后开始会议。
Input
n,q
n,q
,表示字符串的长度和询问的个数。
一行,一个01串s
s
,0表示没有点亮,1表示点亮的灯。
q
q
行,每行两个整数l≤r
l≤r
表示一个询问。
Output
q
q
行,每行输出一个答案,”ephemeral”表示会议很快能够开始,”endless”表示会议再也没法开始了。
Sample Input
5 3
10101
1 2
2 4
2 5
Sample Output
ephemeral
endless
ephemeral
HINT
Subtask1 [10 pts]
n≤10,q≤10
n≤10,q≤10
Subtask2 [20 pts]
r−l+1=2k
r−l+1=2k
Subtask3 [10 pts]
r−l+1=3k
r−l+1=3k
Subtask4 [10 pts]
r−l+1=6k
r−l+1=6k
Subtask5 [50pts]
n≤105,q≤105
n≤105,q≤105
稳爷爷的题 蒟蒻我爆0 的一场考试
copy了下sjzez大爷的题解 希望他不会看到蒟蒻我的blog
手玩一下发现 好像长度为2^k的边都有解,于是写了一个puts(“ephemeral”)骗分。
然而并不会证明QAQ(但是最后竟真的有分)。
说一下正解。
考虑区间长度为len,如果len=r*k,r为循环长度的话。
考虑把长为len的环按照i%r分类,如果i%r相同的每个灯取出来构成的k个长度为r的环,有一个环是endless那么整个就是endless(因为跳蚤们总能只转k的倍数)。
并且如果按照(i-1)/r分类,分成k段长度为r的,如果r是个循环节(也就是说每个小环相同),那么只要小环是ephemeral的,整个环就一定是ephemeral的。
第一个结论并没有什么用途,但是第二个结论十分重要:
假设len=x*(2^k),k为可行的最大整数,那么当且仅当这r段完全相同的时候才会有解。
为什么?显然这r段相同的时候一定有解(我们可以对这r段进行相同的操作,那么旋转相当于在一个循环节内进行,而一个循环节有解),充分性得证。
对于必要性,如果有一段不同,那么这个环上最少有两种状态不同的段,并且这两种段全部点亮的操作序列是不同的(显然不同)。
于是如果对每一段进行相同的操作,则这两种段一定不会同时点亮。
如果进行不同的操作,我们可以通过旋转让最少两个针对某种段的操作不会作用到针对的段上(脑补一下旋转),并且这会生成种类更多的段,于是必要性得证。
感性理解一下,我们现在为(ABB),对应的操作为(XYY),我们通过一次旋转,让最后的序列变成(A^Y)(B^Y)(B^X),当前存在至少两种段,还可以继续操作。
于是我们得到了一种算法:对于长度为len的一段[l,r],我们求出最大的k使得(2^k)|len,然后我们只需要判定[l,r-(2^k)]==[l+(2^k),r]即可。
对于这个判定的证明,自己在纸上画一下即理解充分性和必要性。
关于长度为(2^k)的段一定有解的证明,看官方题解吧……
所以很自然的,我们想要知道长度为2^k是否一定是ephemeral的。
很简单,考虑把它建模成我们有一个多项式f,国王每次给出一个多项式g,跳蚤选一个k,f’ = f + g * x^d
当然了,因为xor和循环,我们等于是在F_2[x] / (x^{2^k} - 1)下做这件事情。
考虑一个策略是国王每次取g = f, 此时f’ = f * (x^d + 1)
而我们在F_2下分解可知x^{2^k} - 1 = (x - 1)^{2^k},同时注意x^d + 1 = x^d - 1 = (x - 1) * F(x)
所以每次都会贡献一个(x - 1)的因子,从而证明了2^k的时候一定是ephemeral的,并且不会超过2^k轮。
从而我们把n = r - l + 1写成2^k * t,每次考虑有没有一个大小为2^k的循环节即可。
对于l==r的情况下 因为hash值的计算公式所以直接这样判断是不会有问题的
#include<cstdio>
#include<algorithm>
#define N 110000
#define g 3
#define ll unsigned long long
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=gc();}
while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();
return x*f;
}int a[N],n,q;
inline void read_(){
int op=0;char ch=gc();
while(ch<'0'||ch>'1') ch=gc();while(ch>='0'&&ch<='1') a[++op]=ch-'0',ch=gc();
}
ll hs[N],p[N];
inline int calc(int l,int r){return hs[r]-hs[l-1]*p[r-l+1];}
int main(){
freopen("t3.in","r",stdin);
n=read();q=read();read_();p[0]=1;
for (int i=1;i<=n;++i) hs[i]=hs[i-1]*g+a[i],p[i]=p[i-1]*g;
for (int owo=1;owo<=q;++owo){
int l=read(),r=read(),len=r-l+1;int k=len&-len;
calc(l,r-k)==calc(l+k,r)?puts("ephemeral"):puts("endless");
}
}