RT,站外题,大体意思是给出一堆询问 l,r,x,求 ∑i=lrCxi。
个人思路是转化为前缀和后,预处理阶乘逆元,离线下来用莫队做,莫队转移时利用组合数前缀和的递推公式求解。
然后写完发现小数据 WA,大数据 RE(不是数组开小),只有 l,r 全部相等的数据 AC,求调/kel
#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
struct node
{
int l,r,b,w;
}q[400005];
int t,n,m,l,r,x,ans[400005],p[200005],mul[200005];
bool cmp(node a,node b)
{
if(a.b!=b.b)return a.b<b.b;
else if(a.b&1)return a.r<b.r;
else return a.r>b.r;
}
int power(int x,int y)
{
int res=1;
while(y)
{
if(y%2)res=res*x%mod;
y/=2;
x=x*x%mod;
}
return res;
}
int C(int x,int y)
{
return p[y]*mul[x]%mod*mul[y-x]%mod;
}
signed main()
{
//freopen("sequence.in","r",stdin);
//freopen("sequence.out","w",stdout);
scanf("%lld",&t);
for(int i=1;i<=t;i++)
{
scanf("%lld%lld%lld",&l,&r,&x);
q[++m].l=l-1;q[m].r=x;
q[++m].l=r;q[m].r=x;
n=max(n,x);
}
p[0]=1;mul[0]=1;
for(int i=1;i<=n;i++)p[i]=p[i-1]*i%mod;
for(int i=1;i<=n;i++)mul[i]=power(p[i],mod-2);
int num=sqrt(n);
for(int i=1;i<=m;i++)
{
q[i].b=(q[i].l-1)/num+1;
q[i].w=i;
}
sort(q+1,q+m+1,cmp);
int l=1,r=0,res=0;
for(int i=1;i<=m;i++)
{
while(l<q[i].l){l++;res=(res+C(l,r))%mod;}
while(l>q[i].l){res=(res-C(l,r)+mod)%mod;l--;}
while(r<q[i].r){res=(2*res-C(l,r)+mod)%mod;r++;}
while(r>q[i].r){r--;res=((res+C(l,r))%mod)*mul[2]%mod;}
ans[q[i].w]=res;
}
for(int i=1;i<=t;i++)printf("%lld\n",(ans[2*i]-ans[2*i-1]+mod)%mod);
return 0;
}