zoukankan      html  css  js  c++  java
  • 牛客网暑期多校 (第十场)

    链接:https://www.nowcoder.com/acm/contest/148/D
    来源:牛客网

    题目描述
    Prefix Sum is a useful trick in data structure problems.

    For example, given an array A of length n and m queries. Each query gives an interval [l,r] and you need to calculate . How to solve this problem in O(n+m)? We can calculate the prefix sum array B in which Bi is equal to . And for each query, the answer is Br-Bl-1.

    Since Rikka is interested in this powerful trick, she sets a simple task about Prefix Sum for you:

    Given two integers n,m, Rikka constructs an array A of length n which is initialized by Ai = 0. And then she makes m operations on it.

    There are three types of operations:
    1. 1 L R w, for each index i ∈ [L,R], change Ai to Ai + 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 .
    输入描述:

    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

    题意 : 给你一个长度为 n 的序列,初始元素均为 0 , 有 3 种操作, 1 是给序列的某一个区间加上同一个元素, 2 是将此序列变为它的前缀和序列, 3 是求序列某一个区间的和 ,数据保证 操作3 的次数不多于 500 次

    思路分析 : 这题想了好久才勉强有点思路,挺不错的一道题目 , 可以这样想,当我们在某一个位置上增加一个数时,再求上几次前缀和,画个表写出来,会发现这其实就是一个斜着的杨辉三角,找到其是哪一行哪一列,直接公式就可以算出来, C(n-1,m-1)。操作 2 的话就累加,操作3的话就进行一次求和计算即可。

    代码示例 :

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const ll maxn = 2e5+5;
    const ll mod = 998244353;
    
    ll n, m;
    struct node{
        ll tt, pos, w;
    }a[maxn];
    ll cnt;
    ll pp[maxn], inv[maxn];
    
    ll qw(ll x, ll n){
        ll res = 1;
    
        while(n > 0){
            if (n & 1) res = res * x % mod;
            x = x * x % mod;
            n >>= 1;
        }
    
        return res%mod;
    }
    
    void init() {
        pp[0] = 1;
        for(ll i = 1; i <= 200000; i++) {
            pp[i] = (pp[i-1]*i)%mod;
            inv[i] = qw(pp[i], mod-2);
        }
        inv[0] = inv[1];
    }
    
    ll C(ll n, ll m){
        ll ans = pp[n]*inv[m]%mod*inv[n-m]%mod;
        return ans%mod;
    }
    
    ll query(ll pos, ll tt){
        ll ans = 0;
        for(ll i = 0; i < cnt; i++){
            if (a[i].pos <= pos) {
                ans += a[i].w*C(pos-a[i].pos+tt-a[i].tt-1, tt-a[i].tt-1)%mod;
                ans %= mod;
            }
        }
        return ans;
    }
    
    int main () {
        ll t;
        ll pt, l, r, w;
        init();
    
        cin >> t;
        while(t--){
            cin >> n >> m;
            cnt = 0; ll tt = 1;
            while(m--){
                scanf("%lld", &pt);
                if (pt == 1){
                    scanf("%lld%lld%lld", &l, &r, &w);
                	a[cnt].tt = tt-1, a[cnt].pos = l, a[cnt].w = w%mod; cnt++;
    				a[cnt].tt = tt-1, a[cnt].pos = r+1, a[cnt].w = -w%mod; cnt++;
    			}
                else if (pt == 2) tt++;
                else {
                    scanf("%lld%lld", &l, &r);
                    printf("%lld
    ", ((query(r, tt+1)-query(l-1, tt+1))%mod+mod)%mod);
                }
            }
        }
    
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    大数加法、乘法实现的简单版本
    hdu 4027 Can you answer these queries?
    zoj 1610 Count the Colors
    2018 徐州赛区网赛 G. Trace
    1495 中国好区间 尺取法
    LA 3938 动态最大连续区间 线段树
    51nod 1275 连续子段的差异
    caioj 1172 poj 2823 单调队列过渡题
    数据结构和算法题
    一个通用分页类
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9510096.html
Copyright © 2011-2022 走看看