【JZOJ 省選模擬】我的朋友們

題目

Description
在這裏插入圖片描述

Input
在這裏插入圖片描述

Output
一行一個整數,表示題目描述中的期望對998244353取模的值。

Sample Input
樣例 1輸入:
4 3
1 5
4 6
3 7
1 7
樣例 2輸入:
4 2
1 5
4 6
3 7
1 7
樣例3輸入:
20 13
4 10
1 3
2 8
1 6
2 8
1 5
2 3
3 7
1 5
2 7
3 7
3 7
3 9
2 3
1 2
4 9
2 3
5 9
3 9
1 2

Sample Output
樣例 1輸出:
801550003
樣例2輸出:
445419837
樣例3輸出:
799993097

Data Constraint
本題採用捆綁測試。所有測試點均滿足
在這裏插入圖片描述

Hint
在這裏插入圖片描述

思路

用ai代替pi

我們將 翻轉。
令:
在這裏插入圖片描述
在這裏插入圖片描述

對於後面那一坨東西,考慮分治FFT。假設現在F1…l-1已知,要計算出[l,r]內的Fi。令:
在這裏插入圖片描述

在這裏插入圖片描述

代碼

#include<bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define mod 998244353
#define ll long long
#define G 3
using namespace std;
const int maxn=262144;
ll aa[maxn],bb[maxn],bb2[maxn],bb3[maxn],cc[maxn],A[maxn],p[maxn],p1[4194304],p2[4194304];
ll f[8388608],g[4194304],a[8388608],b[8388608],c[maxn],ans[maxn],P[maxn];
int bg[maxn],ed[maxn],bg1[maxn],ed1[maxn],bg2[maxn],ed2[maxn],A2[19][maxn],len2[maxn+1],n2[maxn+1];
int n3[maxn+1],W1[19],W2[19],n,L,I,J,i,j,k,l,s,s2,N,N2,len,tot,tot1,tot2;
ll power(ll a,int b)
{
	ll ans=1;
	
	while (b)
	{
		if (b&1)
		ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	
	return ans;
}

void dft(ll *a,int type,int N,int len)
{
	int i,j,k,l,S=N,s1=2,s2=1;
	ll w,W,u,v;
	
	fo(i,0,N-1) A[A2[len][i]]=a[i];
	memcpy(a,A,N*8);
	
	fo(i,1,len)
	{
		S>>=1;
		w=(type==1)?W1[i]:W2[i];
		
		fo(j,0,S-1)
		{
			W=1;
			fo(k,0,s2-1)
			{
				u=a[j*s1+k];
				v=a[j*s1+k+s2]*W;
				
				a[j*s1+k]=(u+v)%mod;
				a[j*s1+k+s2]=(u-v)%mod;
				
				W=W*w%mod;
			}
		}
		
		s1<<=1,s2<<=1;
	}
}

void mul(ll *x,ll *y,int n,int m)
{
	int i,j,k,l,N,N2,len;
	len=len2[n+m];N=n2[n+m];N2=n3[n+m];
	if (n<m)
	fo(i,n,m) x[i]=0;
	else
	fo(i,m,n) y[i]=0;
	fo(i,max(n,m),N-1) x[i]=y[i]=0;
	memcpy(bb3,y,N*8);
	dft(x,1,N,len);
	dft(bb3,1,N,len);
	fo(i,0,N-1) x[i]=x[i]*bb3[i]%mod;
	dft(x,-1,N,len);
	fo(i,0,N-1) x[i]=x[i]*N2%mod;
}
void NTT(ll *x,ll *y,ll *z,int X1,int X2,int Y1,int Y2,int Z1,int Z2,int st)
{
	int i;
	fo(i,X1,X2) aa[i-X1]=x[i];
	fo(i,Y1,Y2) bb[i-Y1]=y[i];
	mul(aa,bb,X2-X1+1,Y2-Y1+1);
	fo(i,Z1,Z2) z[i]=aa[i-Z1+st];
}

void inv(ll *a,int n)
{
	int i,j,k,l;
	
	cc[0]=power(a[0],mod-2);
	for (i=2; i<=n; i*=2)
	{
		memcpy(bb2,a,i*8);
		
		mul(bb2,cc,i,i);mul(bb2,cc,i,i);
		fo(j,0,i+i-1)
		bb2[j]=(2*cc[j]-bb2[j])%mod;
		
		memcpy(cc,bb2,i*8);
	}
	memcpy(a,cc,n*8);
}

void work(int t,int x,int y)
{
	int i,mid=(x+y)/2;
	
	if (x==y)
	{
		bg[t]=tot+1;ed[t]=tot+2;
		
		if (x>L)
		p1[tot+1]=1-p[x-L],p1[tot+2]=p[x-L];
		else
		p1[tot+1]=1,p1[tot+2]=0;
		if (x<n)
		p2[tot+1]=1-p[x+1],p2[tot+2]=p[x+1];
		else
		p2[tot+1]=1,p2[tot+2]=0;
		
		tot+=2;
		return;
	}
	
	work(t*2,x,mid);
	work(t*2+1,mid+1,y);
	
	bg[t]=tot+1;ed[t]=tot+(y-x+1)+1;
	NTT(p1,p1,p1,bg[t*2],ed[t*2],bg[t*2+1],ed[t*2+1],bg[t],ed[t],0);
	NTT(p2,p2,p2,bg[t*2],ed[t*2],bg[t*2+1],ed[t*2+1],bg[t],ed[t],0);
	tot+=(y-x+1)+1;
}

void Work(int t,int x,int y)
{
	int i,mid=(x+y)/2;
	
	if (x==y)
	{
		if (x>=L)
		ans[x]=(f[bg1[t]+1]+1)*power(1-P[x],mod-2)%mod;
		return;
	}
	
	bg2[t*2]=tot2+1;ed2[t*2]=tot2+(mid-x+1);tot2+=mid-x+1;
	NTT(g,p1,g,bg2[t],ed2[t],bg[t*2+1],ed[t*2+1],bg2[t*2],ed2[t*2],0);
	
	bg1[t*2]=tot1+1;ed1[t*2]=tot1+min(n+1,2*(mid-x+1));tot1+=min(n+1,2*(mid-x+1));
	NTT(f,p1,f,bg1[t],ed1[t],bg[t*2+1],ed[t*2+1],bg1[t*2],ed1[t*2],max(0,2*x-mid-1)-max(0,2*x-y-1));
	Work(t*2,x,mid);
	
	
	bg2[t*2+1]=tot2+1;ed2[t*2+1]=tot2+(y-mid);tot2+=y-mid;
	NTT(g,p2,a,bg2[t],ed2[t],bg[t*2],ed[t*2],bg2[t],ed2[t],0);
	fo(i,0,y-mid-1) g[bg2[t*2+1]+i]=a[bg2[t]+i];
	
	bg1[t*2+1]=tot1+1;ed1[t*2+1]=tot1+min(n+1,2*(y-mid));tot1+=min(n+1,2*(y-mid));
	NTT(f,p2,b,bg1[t],ed1[t],bg[t*2],ed[t*2],bg1[t*2+1],ed1[t*2+1],max(0,2*mid-y+1)-max(0,2*x-y-1));
	fo(i,x,mid) c[i]=ans[i];
	NTT(c,a,a,x,mid,bg2[t],ed2[t],bg1[t*2+1],ed1[t*2+1],max(0,2*mid-y+1)-x);
	
	fo(i,bg1[t*2+1],ed1[t*2+1]) f[i]=(a[i]+b[i])%mod;
	Work(t*2+1,mid+1,y);
}

int main()
{
	freopen("friends.in","r",stdin); freopen("friends.out","w",stdout);
	I=2;J=1;s=2;len2[1]=1;n2[1]=2;n3[1]=499122177;
	fo(len,0,18)
	{
		if (len<18)
		W1[len+1]=power(G,(mod-1)/s),W2[len+1]=power(W1[len+1],mod-2);
		
		s2=power(s,mod-2);
		fo(i,0,J-1)
		{
			if (I<=maxn)
			len2[I]=len+1,n2[I]=s,n3[I]=s2,++I;
			
			j=i;k=0;
			fo(l,1,len)
			k=(k<<1)+(j&1),j>>=1;
			
			A2[len][i]=k;
		}
		J*=2;s=s*2;
	}
	scanf("%d%d",&n,&L);
	fd(i,n,1)
	{
		scanf("%d%d",&p[i],&j);
		p[i]=p[i]*power(j,mod-2)%mod;
	}
	P[L]=1;
	fo(i,1,L) P[L]=P[L]*(1-p[i])%mod;
	fo(i,L+1,n) P[i]=P[i-1]*(1-p[i])%mod*power(1-p[i-L],mod-2)%mod;
	work(1,1,n);
	tot1=n+1;bg1[1]=1;ed1[1]=n+1;
	tot2=n+1;bg2[1]=1;ed2[1]=n;
	a[1]=p[1],a[0]=1-p[1];
	fo(i,0,n)
	b[i]=p1[bg[1]+i];
	N=pow(2,ceil(log2(n+1)));
	inv(b,N);
	NTT(a,b,g,0,1,0,N-1,1,n,0);
	Work(1,1,n);
	printf("%lld\n",(ans[n]+mod)%mod);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章