Codeforces 755 G. PolandBall and Many Other Balls

Description

\(n\)个球,每组一个或者相邻的两个,求分成\(k\)组的方案数。\(n\leqslant 10^9,k<2^{15}\)

Solution

DP+FNT.

转移\(f[i][j]=f[i-1][j]+f[i-1][j-1]+f[i-2][j-1]\)

这个不是很好维护...可以看成多项式来做...可惜我也不太会...

还有一个转移就是折半来做,前一段为\(x\),后一段为\(y\),\(x+y=i\)。

若恰好在\(x,y\)之间可以分开那么方案数就是

\(f[i][j]=\sum_{a=0}^{k}\sum_{b=0}^{k}[a+b=j]f[x][a]\times f[y][b]\)

如果不能那么就是

\(f[i][j]=\sum_{a=0}^{k}\sum_{b=0}^{k}[a+b=j-1]f[x-1][a]\times f[y-1][b]\)

然后就可以倍增了...这个转移可以用FNT优化...

我写的常数巨大...卡了一晚上常数 = =。最后吧合并展开了少了几次DFT的操作...

Code

#include 
using namespace std;

#define debug(a) cout<<(#a)<<"="<>1)

typedef long long LL;
typedef pair pr;
typedef vector vi;
typedef vector vl;
typedef vector vs;
const int N = 1<<17;
const int M = 32;
const int oo = 0x3f3f3f3f;
const LL  OO = 1e18;

const int p = 998244353;
LL Pow(LL a,LL b,LL r=1) { for(;b;b>>=1,a=a*a%p) if(b&1) r=r*a%p;return r; }
LL Pow(LL a,LL b,LL p,LL r=1) { for(;b;b>>=1,a=a*a%p) if(b&1) r=r*a%p;return r; }
LL inv(LL x) { return Pow(x,p-2); }
void Add(int &x,LL y) { x=(x+y%p)%p; }
void Sub(int &x,LL y) { x=(x-y%p+p)%p; }
void Mul(int &x,LL y) { x=x*(y%p)%p; }
int chkmax(LL &x,LL y) { return xy?x=y,1:0; }

inline LL in(LL x=0,char ch=getchar(),int v=1) {
	while(ch>'9' || ch<'0') v=ch=='-'?-1:v,ch=getchar();
	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*v;
}
/*end*/

namespace Pol {
	const int g = 3;
	int pn = 1<<15;
	int nn = pn<<1;
	
	int rev[N];
	int w[M][N];
	
	void init(int n) { for(pn=1;pn>1;(j^=k)>=1);
		}
		for(int i=1,l=0;i<=n;i<<=1,++l){
			w[l][0]=Pow(g,(p-1)/i);
			w[l][1]=Pow(w[l][0],p-2);
		}
	}
	void Rev(int a[],int n=nn) {
		for(int i=0;irev[i]) swap(a[i],a[rev[i]]);
	}
	void DFT(int a[],int r=1,int n=nn) {
		Rev(a);
		for(int i=2,l=1;i<=n;i<<=1,l++) {
			for(int j=0;j=0) c[i]=(c[i]+t3[i-t])%p;
}*/


int main() {
	ios::sync_with_stdio(false);
//	cout<<(sizeof(f)+sizeof(ans)+sizeof(t1)*3)/1024.0/1024.0<>n>>k;
	Pol::init(max(8LL,k));
	Pol::pre();
	
{
	f[0][0][0]=0;
	f[0][1][0]=1;
	get_2(f[0]);
	int i=0;
	int *t1=g[i][0],*t2=g[i][1],*t3=g[i][2];
	for(int j=0;j>i)&1) {
		cur^=1;
		if(!fst) {
			for(int j=0;j

  

转载于:https://www.cnblogs.com/beiyuoi/p/6654361.html

你可能感兴趣的:(Codeforces 755 G. PolandBall and Many Other Balls)