srm 551
srm 550
srm 549
srm 548
srm 547
srm 546
srm 545
srm 518(有FWT的题QvQ)
250
Description
从一个字符串中找一字典序最大的字串
Solution
从左至右贪心即可
500
Description
有一个序列,每次可以将一个数$-1$需要花费$1$的代价,问最后使得序列满足$2a[i]\le a[i-1]+a[i+1]$
Solution
因为满足$a[i-1]-a[i]\ge a[i]-a[i+1]$,也就是说序列相邻两项差是递减的,所以每当不满足条件时暴力调整$a[i]$,直到不需要调整为止。想想极限数据调整次数即可直到复杂度是靠谱的。
1000
Description
求符合以下条件的序列个数
- 1:长度为K
- 2:每个元素大小不超过L
- 3:每个数都是质数
- 4:所有数异或和为0
$K\le{10^{9}},L\le{5\times{10^{4}}}$
Solution
基本的递推方程很容易列出来$f[i][j]$表示前$i$个数异或和为$j$的方案数
$f[i][x\otimes y]=\sum_{0\le x,y\le 2^{16}} f[i-1][x]\times f[1][y]$
$f[1][y]=1$当且仅当$y$为质数且$y\le L$
这样暴力递推显然是$O(KL^2)$的,$i$为偶数时分治一下可以做到$O(L^2\times logK)$的,复杂度还是不行
然后我们可以想到把这个东西搞成类似于FFT的东西。
设向量a,b,c,定义向量之间的运算$ \$,c=a \$ b $
$c[i\otimes j]=\sum a[i]\times b[j],做变换tf,使得tf(a\$b)=tf(a)\times tf(b),逆变换dft(tf(x))=x$
设$a$向量,$a[i]$表示$i$堆石子异或和为$0\sim 2^{16}$的方案数,$a[1]$在素数位置处为$1$,其他位置为$0$
这样我们只需要用$logK$的时间算出$tf(a[1])^K$,在做逆变换得到$a[k]$即为答案
观察tf和dtf的性质,当只有一个元素时,$tf(x)=dtf(x)=x$
当有两个元素$X=(a,b),Y=(c,d)$时
$Z=X\$Y$
$Z[0]=X[0]\times Y[0]+X[1]\times Y[1]=ac+bd$
$Z[1]=X[0]\times Y[1]+X[1]\times Y[0]=ad+bc$
$另tf(a,b)=(a-b,a+b)$
则$tf(X)\times tf(Y) =(a-b,a+b)\times(c-d,c+d)$
$=((a-b)\times(c-d),(a+b)\times(c+d))$
$=(ac+bd-ad-bc,ac+bd+ad+bc)$
$=tf(ac+bd,ac-bd)$
$=tf((a,b)\$(c,d))$
$=tf(X\$Y)$
$有A,B两向量,用归纳法可证明出tf(A + B) = tf(A) + tf(B) $
$如果我们将X向量分成两段等长的向量X[1],X[2]$
我们归纳一下会发现$tf(X[1],X[2])=(tf(X1) - tf(X2), tf(X1) + tf(X2))$
$(X[1]-X[2])[i]=X[1][i]-X[2][i]$
$(X[1]+X[2])[i]=X[1][i]+X[2][i]$
$将A分为A[1],A[2],B分为B[1],B[2]$
$则依旧可以归纳证出tf( (A1,A2) \$ (B1,B2) ) = tf(A1,A2)\times{tf(B1,B2)}$
$即对任意向量A,B,tf(A\$B)=tf(A)\times{tf(B)}$
$说明当有两个元素时,tf(a,b)=(a-b,a+b)正好就是我们所需要的变换$
然后我们就可以用$tf(X[1],X[2])=(tf(X1) - tf(X2), tf(X1) + tf(X2))$来做啦
算出$tf(a[1])^K$,在做逆变换得到a[K]即为答案
还有不明白的可以看http://apps.topcoder.com/wiki/display/tc/SRM+518
Code
1 | #include<bits/stdc++.h> |