• 牛客多校10 D Rikka with Prefix Sum 不是数据结构


    https://www.nowcoder.com/acm/contest/148/D

    题意:

    1e5个数,1e5个操作,操作分为:

    1、区间加。

    2、整个数列替换为前缀和。

    3、区间查询。 查询数小于500.

    题解:比赛时的思路是:(基本正确,没能实现)

    1.对于某个操作1,记录下其之后操作2的个数,就可以通过组合数O(1)算出该区间的每个数最终的结果。

    2.各个操作1相互独立,分开来算,最后相加。(暴力出来的规律)

    没想到的两点:

    1.可以通过组合数O(1)算出区间和:用公式

    之前碰到过,杨辉三角上很明显。但直接导致我认为这个想法还是O(n*n/2)orz。

    2.考虑某次区间加之后,操作2对该区间后面的数的影响:可以认为l~n加了v,r+1到n加了-v 正好抵消

    另外:尝试了快速mod模板

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<map>
    #include<string>
    #include<bitset>
    
    #define re register
    #define rep(i,s,t) for(re int i=s;i<=t;++i)
    #define per(i,s,t) for(re int i=s;i>=t;--i)
    #define mmm(f,x) memset(f,x,sizeof f)
    //#define x first
    //#define xx second
    using namespace std;
    
    typedef  long long ll;
    
    const ll mod = 998244353;
    template<typename T>inline void add_(T &A, int B, ll MOD = mod) { A += B; (A >= MOD) && (A -= MOD); }
    template<typename T>inline void mul_(T &A, ll B, ll MOD = mod) { A = (A*B) % MOD; }
    template<typename T>inline void mod_(T &A, ll MOD = mod) { A %= MOD; A += MOD; A %= MOD; }
    const int maxn = 3e5 + 5;
    int a[maxn];
    int n, m;
    int tot,Q;
    ll L[maxn], R[maxn],W[maxn],num2[maxn];
    ll inv[maxn],  fac[maxn];
    ll c[maxn];
    long long kpow(long long a, long long n) {
        long long res = 1;
        while (n > 0) {
            if (n & 1)res = res * a%mod;
            a = a * a%mod;
            n >>= 1;
        }
        return res;
    }
    void init() {
        fac[0] = fac[1] = 1;
        inv[1] = 1;
        rep(i, 2, maxn) {
            fac[i] = fac[i - 1] * (ll)i % mod;
            inv[i] = kpow(fac[i], mod - 2);
        }
    }
    ll C(int n, int m) {
        if (n < m) return 0ll;
        if (m == 0 || n == m) return 1ll;
        if (n - 1 == m || m == 1) return n;
        return fac[n] * inv[m] % mod * inv[n - m] % mod;
    }
    ll Csum(ll l, ll r, ll v, ll q) {
        if (l>r)return 0;
        ll n = r - l + 1;
        ll ans = v;
        mul_(ans,C(q + n - 1, q));
        mod_(ans);
        return ans;
    }
    ll query(int x) {
        ll ret = 0;
        rep(i, 1, tot) {
            int q = Q - num2[i] + 1;
            if (L[i] > x)continue;
            if (R[i] <= x) {
                add_(ret, Csum(L[i], x, W[i], q));
                add_(ret, Csum(R[i] + 1, x, -W[i], q));
                mod_(ret);
            }
            else add_(ret, Csum(L[i], x, W[i], q));
        }
        return ret;
    }
    int main() {
        init();
        int t;
        cin >> t;
        while (t--) {
            tot = 0,Q=0;
            cin >> n >> m;
            rep(i, 1, m) {
                int op;
                scanf("%d", &op);
                if (op == 2) {
                    Q++;
                }
                else {
                    ll l, r;
                    scanf("%lld%lld", &l, &r);
                    
                    if (op == 1) {
                        ll w; 
                        scanf("%lld", &w);
                        L[++tot] = l, R[tot] = r; W[tot] = w;
                        num2[tot] = Q;
                    }
                    else { cout<< (query(r) - query(l - 1) + mod) % mod << endl; }
                }
            }
        }
    }
    /*
    1
    100000 7
    1 1 3 1
    2
    3 2333 6666
    2
    3 2333 6666
    2
    3 2333 6666
    */
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    双六
    除法取模
    欧拉函数及费马小定理
    基础模运算
    Leeetcode--581. Shortest Unsorted Continuous Subarray
    Codeforces Round #541--1131F. Asya And Kittens(基础并查集)
    leetcode--200. Number of Islands
    leetcode--21. Merge Two Sorted Lists
    leetcode--155. Min Stack
    Codeforces Round #539--1113B
  • 原文地址:https://www.cnblogs.com/SuuT/p/9502766.html
Copyright © 2020-2023  润新知