LGP8442题解

赛前和出题人击过剑,交换了JROI R4和LMOI R1的E和F,并且保证互相不打对方的比赛(

这个做法得到了出题人的许可(

其实六道题都看过并且口胡过一遍,但是对面没看过JROI的前四道题

这个模数可以变成两个数的乘积,即 \(2.4\times 10^7+1\)\(3\times 10^7+1\)

不难发现 \(n\) 的范围中除了 \(13\) 都是这两个数减去 \(1\) 的因数。

而题目要求的是 \((x+x^{n-1})^m\pmod{x^n-1}\),循环卷积的长度是 p-1 的因数当然非常快乐。

于是我们收获了一个单次 \(O(n\log n)\) 的做法。

并且注意到其实你只需要求零次项,idft的时候直接暴力带入 \(\omega_n^0\) 或者直接拉格朗日插值即可,复杂度 \(O(n+n\log mod)\)

但是呢,快速幂是没有必要的。我们使用原根做乘法,直接预处理原根的幂,加法的时候用 \(\ln\) 转移下即可做到 \(O(n)\)

\(m\) 显然是可以对 \(mod-1\) 取模的。

然后考虑把传球的那颗树画出来,不难发现到达这棵树最底部的方案数是组合数,而你只需要求 \(O(\frac{m}{n})\) 个位置的组合数。

于是又收获了一个 \(O(\frac{mod}{n})\) 的做法。

根号分治一下,能够得到单次 \(O(\sqrt{mod})\) 的做法。虽然有 2500 次询问但是一定能跑。

出题人原本认为 \(n=13\) 是最难的部分。

于是我贺了一个 Berlekamp–Massey,很快啊,递推式直接扒出来了。

\[f_n=f_{n-1}+7\times f_{n-2}-6\times f_{n-3}-14\times f_{n-4}+9\times f_{n-5}+7\times f_{n-6}-2\times f_{n-7} \]

然后跑一个常系数齐次线性递推直接单次 \(O(7^2\sum\log m)\) 随便乱草。

如果觉得不够过瘾可以写成矩阵乘法,然后用特征多项式优化矩快来一个 \(O(13^4+13^2\sum\log m)\) 狂暴轰入。

但是实际上 \(\sum\log m\) 有 2.5e7,跑个锤子啊!

只能考虑循环节了。对于 \(p=3\times 10^7+1\),有 \((x+x^{12})^p\equiv\sum_{i=0}^{p}\binom{p}{i}x^ix^{12i}\equiv x^{12p}+x^p\equiv x^5+x^8\pmod{x^{13}-1}\)

然后能发现 \((x^5+x^8)^p\equiv x^{5p}+x^{8p}\equiv x+x^{12}\pmod{x^{13}-1}\)

也就是说 \(p^2\) 一定是模 \(3\times 10^7+1\) 的循环节。

同理模 \(2.4\times 10^7+1\) 的循环节是 \(2.4\times 10^7\)

做一个 lcm 可以发现循环节为 \(1800000120000000ll\),可以薄纱了。

#include<cstring>
#include<cstdio>
typedef unsigned long long ull;
typedef __uint128_t LL;
typedef unsigned ui;
const ui M=3e7+5,mod1=2.4e7+1,mod2=3e7+1,MOD1=mod1-1,MOD2=mod2-1;
const ull MOD=720000054000001ll,MD=1800000120000000ll;
ui n,m,m1,m2,a[M];char s[10005];
template<const ui mod,const ui g>
struct SolveP{
	ui fac[mod/3000],ifac[mod];
	inline ui pow(ui a,ui b=mod-2){
		ui ans(1);for(;b;b>>=1,a=1ull*a*a%mod)if(b&1)ans=1ull*ans*a%mod;return ans;
	}
	inline void init(){
		ui c(1);fac[0]=1;for(ui i=2;i<mod;++i)if(c=1ull*c*i%mod,!(i%3000))fac[i/3000]=c;
		c=pow(c);for(ui i=mod-1;i<mod;--i)ifac[i]=c,c=1ull*c*i%mod;
	}
	inline ui S(const ui&n,const ui&m){
		return 1ull*ifac[m]*ifac[n-m]%mod;
	}
	inline ui Solve1(const ui&n,const ui&m){
		ui sum(0);const ui&c=pow(g,(mod-1)/n),&ic=pow(g,mod-1-(mod-1)/n);
		for(ui x(c),y(ic),i=1;(i<<1)<n;++i)sum=(sum+pow((x+y)%mod,m))%mod,x=1ull*x*c%mod,y=1ull*y*ic%mod;
		return(2ull*sum+pow(2,m)+pow(mod-2,m))%mod*pow(n)%mod;
	}
	inline ui Solve2(const ui&n,const ui&m){
		const int&lim=m/n;ui sum(0),Fac(fac[m/3000]);for(ui i=ui(m/3000)*3000+1;i<=m;++i)Fac=1ull*Fac*i%mod;
		for(int i=-lim;i<=lim;++i)if(!(m+i*n&1))sum=(sum+1ull*Fac*S(m,m+i*n>>1))%mod;return sum;
	}
};SolveP<mod1,23>T1;SolveP<mod2,14>T2;
namespace Solve13{
	const ull mod=720000054000001ll,p[8]={mod-1,1,7,mod-6,mod-14,9,7,mod-2},q[7]={1,0,2,0,6,0,20};
	struct Poly{
		ull f[7];
		Poly(){f[0]=f[1]=f[2]=f[3]=f[4]=f[5]=f[6]=0;}
		inline ull&operator[](const ui&x){
			return f[x];
		}
		inline Poly operator*(Poly g){
			static ull tmp[13];static Poly ans;
			for(ui i=0;i^7;++i)for(ui j=0;j^7;++j)tmp[i+j]=(tmp[i+j]+(LL)f[i]*g[j])%mod;
			for(ui i=12;i>=7;--i)if(const ull c=tmp[i])for(ui j=0;j^8;++j)tmp[i-j]=(tmp[i-j]+(LL)c*p[j])%mod;
			for(ui i=0;i^7;++i)ans[i]=tmp[i],tmp[i]=0;return ans;
		}
	};
	inline ull Qry(ull m){
		Poly ans,base;ans[0]=base[1]=1;for(;m;m>>=1,base=base*base)if(m&1)ans=ans*base;
		ull sum(0);for(ui i=0;i^7;++i)sum=(sum+ans[i]*q[i])%mod;return sum;
	}
}
inline ull CRT(ui a,ui b){
	return((LL)23999997ll*mod2*a+(LL)5ll*mod1*b)%MOD;
}
signed main(){
	T1.init();T2.init();
	while(~scanf("%u%s",&n,s+1)){
		m=strlen(s+1);for(ui i=1;i<=m;++i)a[i]=s[i]-48,s[i]='\0';m1=m2=0;
		if(n==13){
			ull x=0;for(ui i=1;i<=m;++i)x=(10*x+a[i])%MD;
			printf("%llu\n",Solve13::Qry(x));
		}
		else{
			for(ui i=1;i<=m;++i)m1=(10*m1+a[i])%MOD1,m2=(10*m2+a[i])%MOD2;
			printf("%llu\n",n<=1000?CRT(T1.Solve1(n,m1),T2.Solve1(n,m2)):CRT(T1.Solve2(n,m1),T2.Solve2(n,m2)));
		}
	}
}
posted @ 2022-07-18 14:23  Prean  阅读(19)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};