2024牛客暑期多校訓練營4 - J. Zero (卡常)

Jerrycyx發表於2024-10-14

\(O(N^2)\) AC。

輸入後預處理 ? 數量的字首和。

雙層迴圈找所有的區間 \([l,r]\) 使區間內沒有 \(0\),找到以後直接用逆元+快速冪求 \(\frac{(r-l+1)^k}{2^{sum_{r}-sum_{l-1}}}\),最後累加和。

因為資料過水,這樣已經能 AC 了。

#include<cstdio>
using namespace std;

const int N=1e5+5,P=998244353;
int n,k;
char str[N];
int qsum[N]; //the number of '?' in str[1,i]

int quick_pow(long long x,int y)
{
	long long res=1;
	while(y)
	{
		if(y&1) res=res*x%P;
		x=x*x%P;
		y>>=1;
	}
	return (int)res;
}
inline int inv(int x)
{
	return quick_pow(x,P-2);
}

int main()
{
	scanf("%d%d",&n,&k);
	scanf("%s",str+1);
	for(int i=1;i<=n;i++)
		qsum[i]=qsum[i-1]+(str[i]=='?');
	long long ans=0;
	for(int l=1;l<=n;l++)
	{
		if(str[l]=='0') continue;
		for(int r=l;r<=n;r++)
		{
			if(str[r]=='0') break;
			int q=qsum[r]-qsum[l-1];
			ans=(ans+1ll*inv(quick_pow(2,q))*quick_pow(r-l+1,k))%P;
		}
	}
	printf("%lld\n",ans);
	return 0;
}

然而,還沒有到極限。

預處理出所有的 \(2^i \bmod 998244353, i \in [0,n]\)\(i^k \bmod 998244353, i \in [0,n]\),這樣過程中就可以不用重複計算。

但還不夠,inv(quick_pow(2,q)) 同樣可以預處理,所以在前面同時預處理 \((2^i)^{-1} \bmod 998244353\),這樣過程中也不用計算逆元了。

#include<cstdio>
using namespace std;

const int N=1e5+5,P=998244353;
int n,k;
char str[N];
int qsum[N]; //the number of '?' in str[1,i]
int binpow[N],powk[N],invbinpow[N];

int quick_pow(long long x,int y)
{
	long long res=1;
	while(y)
	{
		if(y&1) res=res*x%P;
		x=x*x%P;
		y>>=1;
	}
	return (int)res;
}
inline int inv(int x)
{
	return quick_pow(x,P-2);
}

int main()
{
//	freopen("zero.in","r",stdin);
//	freopen("zero.out","w",stdout);
	
	scanf("%d%d",&n,&k);
	scanf("%s",str+1);
	binpow[0]=1;
	invbinpow[0]=inv(binpow[0]);
	for(int i=1;i<=n;i++)
	{
		qsum[i]=qsum[i-1]+(str[i]=='?');
		binpow[i]=binpow[i-1]<<1;
		if(binpow[i]>=P) binpow[i]-=P;
		invbinpow[i]=inv(binpow[i]);
		powk[i]=quick_pow(i,k);
	}
	long long ans=0;
	for(int l=1;l<=n;l++)
	{
		if(str[l]=='0') continue;
		for(int r=l;r<=n;r++)
		{
			if(str[r]=='0') break;
			int q=qsum[r]-qsum[l-1];
			ans=(ans+1ll*invbinpow[q]*powk[r-l+1])%P;
		}
	}
	printf("%lld\n",ans);
	return 0;
}

相關文章