NC17694. Rikka with Prefix Sum
描述
输入描述
The first line contains a single number t(1≤ t ≤ 3), the number of the testcases.
For each testcase, the first line contains two integers n,m(1 ≤ n,m ≤ 105).
And then m lines follow, each line describes an operation(1 ≤ L ≤ R≤ n, 0 ≤ w ≤ 109).
The input guarantees that for each testcase, there are at most 500 operations of type 3.
输出描述
For each query, output a single line with a single integer, the answer modulo 998244353.
示例1
输入:
1 100000 7 1 1 3 1 2 3 2333 6666 2 3 2333 6666 2 3 2333 6666
输出:
13002 58489497 12043005
C++14(g++5.4) 解法, 执行用时: 1048ms, 内存消耗: 7488K, 提交时间: 2018-08-24 16:25:32
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5; const int mod=998244353; ll fac[2*N+5],inv[2*N+5]; struct node{ int x,w,t; }s[2*N]; int cnt; int t; ll fpow(ll a,ll b) { ll ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } ll C(int n,int m) { return fac[n]*inv[m]%mod*inv[n-m]%mod; } void init(int n) { fac[0]=1; for(int i=1; i<=n; i++) fac[i]=i*fac[i-1]%mod; inv[n]=fpow(fac[n],mod-2); for(int i=n-1; i>=0; i--) inv[i]=inv[i+1]*(i+1)%mod; } ll query(int x,int now) { ll ans=0; for(int i=0; i<cnt; i++) if(s[i].x<=x) ans=(ans+C(now-s[i].t+x-s[i].x,x-s[i].x)*s[i].w)%mod; return ans; } void solve() { int op,n,m; int l,r,w; cin>>n>>m; cnt=0; t=0; for(int i=0; i<m; i++) { scanf("%d",&op); if(op==2) t++; else if(op==1) { scanf("%d%d%d",&l,&r,&w); s[cnt++]=(node){l,w%mod,t}; s[cnt++]=(node){r+1,(mod-w)%mod,t}; } else { scanf("%d%d",&l,&r); printf("%lld\n",(query(r,t+1)-query(l-1,t+1)+mod)%mod); } } } int main() { int T; init(2*N); cin>>T; while(T--) solve(); return 0; }
C++(clang++11) 解法, 执行用时: 653ms, 内存消耗: 13816K, 提交时间: 2020-11-21 15:47:16
#include<bits/stdc++.h> #define F first #define S second #define pb push_back using namespace std; const int maxn=1e6+100; typedef long long ll; const int M=998244353; struct node{ int x,y,v; }; vector<node> a; int inv[maxn],nf[maxn],f[maxn],n,cur,q; int F(int x,int y){return 1ll*f[x+y]*nf[x]%M*nf[y]%M;} int qry(int x){ int res=0; for (auto p:a) if (p.y<=x){ int cof=F(cur+1-p.x,x-p.y); res=(res+1ll*cof*p.v)%M; } return res; } int main(){ inv[1]=1; for (int i=2;i<maxn;i++) inv[i]=M-1ll*(M/i)*inv[M%i]%M; f[0]=nf[0]=1; for (int i=1;i<maxn;i++) f[i]=1ll*f[i-1]*i%M,nf[i]=1ll*nf[i-1]*inv[i]%M; int _; scanf("%d",&_); while (_--){ a.clear(); cur=1; scanf("%d%d",&n,&q); while (q--){ int op;scanf("%d",&op); if (op==1){ int l,r,w;scanf("%d%d%d",&l,&r,&w); w%=M; a.pb((node){cur,l,w}); a.pb((node){cur,r+1,M-w}); } else if (op==2){ cur++; } else { int l,r; scanf("%d%d",&l,&r); printf("%d\n",(qry(r)-qry(l-1)+M)%M); } } } return 0; }