zoukankan      html  css  js  c++  java
  • 牛客网暑期ACM多校训练营(第十场)D Rikka with Prefix Sum (数学)

    Rikka with Prefix Sum

    题意:

    给出一个数组a,一开始全为0,现在有三种操作:

    1.  1 L R W,让区间[L,R]里面的数全都加上W;

    2.  2     将a数组变为其前缀和数组;

    3.   3 L R 询问此时a数组区间[L,R]的和。

    题解:

    第一种操作我们可以简化为a[L]+W,a[R+1]-W,利用差分数组的思想。

    接下来这一步使关键,考虑i这个位置有值a[i],然后经过多次2操作对后面的值的贡献,先可以从a[i]=1考虑,然后推广就是了= =

    发现1这个数对后面位置的贡献随着位置的增加与组合数有关,这个可以自己去找下规律。

    然后还有一个就是求区间和的时候,可以从组合数的性质C(i,j)=C(i-1,j-1)+C(i-1,j)去推导。

    最后一点,由于一开始我们对区间修改是对点修改的,假设对点修改后进行了i次2操作,现在求区间和时,其实是求i+1次2操作后的区间和,这一步如果之前第二步推好了是很好解决的。

    注意上面几点是息息相关的,需要自己耐心地找规律。

    另外再稍微提醒一下,由于组合数二维数组预处理空间开不下,所以只能利用阶乘来算,后面取模时就涉及到了逆元。如果不清楚逆元可以去看看 费马小定理。

    逆元可以直接用快速幂来求,但我直接求T了,所以用一个数组事先预处理一下...

    因此要预处理两个数组出来,同时数组长度要开大一倍,这把上面推好了自然就知道了~

    给出代码吧:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 2e5+5,MOD = 998244353;
    int t,n,m,tot;
    int l[N],r[N],w[N],s[N];
    ll fac[N],inv[N];
    ll qp(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(ll a,ll b){
        return fac[a]*qp(fac[b]*fac[a-b]%MOD,MOD-2)%MOD;
    }
    ll query(ll L,ll R,ll cnt){
        if(L-1<0) return C(cnt+R+2,R)%MOD;
        return ((C(cnt+R+2,R)-C(cnt+L+1,L-1))%MOD+MOD)%MOD;
    }
    int main(){
        scanf("%d",&t);
        fac[0]=1;
        for(int i=1;i<=2e5;i++) fac[i]=fac[i-1]*i%MOD;
        while(t--){
            tot=0;memset(s,0,sizeof(s));
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++){
                int op;
                scanf("%d",&op);
                if(op==1){
                    scanf("%d%d%d",&l[tot],&r[tot],&w[tot]);
                    r[tot]++;
                    tot++;
                }else if(op==2) s[tot-1]++;
                else{
                    int L,R;
                    scanf("%d%d",&L,&R);
                    ll ans = 0;
                    int cnt = 0;
                    for(int i=tot-1;i>=0;i--){
                        cnt+=s[i];
                        if(l[i]<=R)
                            ans=(ans+(ll)w[i]*query(max(l[i],L)-l[i],R-l[i],cnt-1)%MOD)%MOD;
                        if(r[i]<=R)
                            ans=(ans-(ll)w[i]*query(max(r[i],L)-r[i],R-r[i],cnt-1)%MOD+MOD)%MOD;
                    }
                    printf("%lld
    ",ans);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    AndroidUI 控件命名格式
    VoIP常见编码的带宽计算
    Hessian 原理分析
    关于异步,同步,阻塞与非阻塞
    dubbo 官方参考手册~备案(防止哪天阿里一生气把dubbo给删除了)
    企业常用的RPC框架比较
    SpringMVC整合Hessian访问远程服务
    Hessian与Webservice的区别
    Dubbo与Zookeeper、Spring整合使用
    java.lang.ClassNotFoundException: org.I0Itec.zkclient.exception.ZkNoNodeException 异常 如何处理
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10182079.html
Copyright © 2011-2022 走看看