牛客多校第十场D(前缀和与组合数)

题意:长度为n的序列,初始都是0,维护3个操作:

There are three types of operations:
1. 1 L R w, for each index i ∈ [L,R], change Ai to A+ w.
2. 2, change A to its prefix sum array. i.e., let A' be a back-up of A, for each i ∈ [1,n], change Ai to .
3. 3 L R, query for the interval sum .

题解:

补充:j位置在i位置后面,组合数的得来类似走网格的方案数

下个结论借助前缀和差分的思想

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<sstream>
 6 #include<ctime> 
 7 #include<cassert> 
 8 #include<iostream>
 9 #include<vector>
10 using namespace std;
11 typedef long long ll;
12 const ll mod = 998244353;
13 const int N=200005;
14 ll fact[N], ifact[N], inv[N];
15 
16 void init() {
17     fact[0] = 1;
18     for(int i=1;i<=N-1;i++) fact[i] = fact[i-1] * i % mod;
19     inv[1] = 1;
20     for (int i = 2; i <= N-1; i++)
21         inv[i] = (mod - mod / i) * inv[mod % i] % mod;
22     ifact[0] = 1;
23     for(int i=1;i<=N-1;i++) ifact[i] = ifact[i-1] * inv[i] % mod;
24 }
25 ll C(ll a,ll b)
26 {
27     if(b>a||a<0||b<0) return 0;
28     return (fact[a]*ifact[b]%mod)*ifact[a-b]%mod;
29 }
30 struct node{
31     int tt,pos;
32     ll w;    
33 };
34 
35 int main()
36 {
37     int t;
38     init();
39     cin>>t;
40     while(t--)
41     {
42         int n,m;
43         cin>>n>>m;
44         int tot=0;
45         vector<node>vt;
46         while(m--)
47         {
48             int op,l,r;
49             ll w;
50             scanf("%d",&op);
51             if(op==1)
52             {    scanf("%d%d%lld",&l,&r,&w);
53                 int x=tot-1;
54             
55                 vt.push_back((node){x,l,w});
56                 vt.push_back((node){x,r+1,-w});
57             }
58             else if(op==2) tot++;
59             else
60             {
61                 scanf("%d%d",&l,&r);
62                 
63                 ll suml=0,sumr=0;
64                 int x=tot+1,l2=vt.size();
65                 
66                 for(int i=0;i<l2;i++)
67                 {
68                     if(vt[i].pos<=l-1)
69                     {
70                         suml+=C(x-vt[i].tt+l-1-vt[i].pos-1,x-vt[i].tt-1)*vt[i].w%mod;
71                         suml%=mod;
72                     }
73                     if(vt[i].pos<=r)
74                     {
75                         sumr+=C(x-vt[i].tt+r-vt[i].pos-1,x-vt[i].tt-1)*vt[i].w%mod;
76                         sumr%=mod;
77                     }
78                 }
79                 printf("%lld\n",(sumr-suml+2ll*mod)%mod);
80                 
81             }
82         }
83     }
84 }
85  

猜你喜欢

转载自www.cnblogs.com/lnu161403214/p/9545465.html
今日推荐