zoukankan      html  css  js  c++  java
  • 牛客暑假多校 H Prefix sum

    题意:

    现在有一个2维矩阵, 初始化为0。 并且这个矩阵是及时更新的。 dp[i][j] = dp[i-1][j] + dp[i][j-1];

    现在有2种操作:

    0 x y   dp[1][x] += y

    1 x  查询dp[k][x]的值。

    题解:

    神奇的分块算法。

    首先我们可以发现 如果在一个 x 的位置加上了值 y 那么 在 x' 的位置加上的值是 从 (1, x) 走到 (k,x')的方案数* y, 只能向下向右移动。

    现在我们有2种最暴力的做法:

    1 每次更新都暴力更新整个矩阵  然后o1得到结果

    2 每次都把添加的数存一下 然后询问的时候通过组合数去找到答案。

    这两种做法复杂度都很爆炸。

    但是 如果把这2种做法结合一下, 每次都把添加的值存起来,然后询问的时候通过组合数去找答案, 然后当存了的数大于一定的数目的时候再暴力更新整个矩阵。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
     4 #define LL long long
     5 #define ULL unsigned LL
     6 #define fi first
     7 #define se second
     8 #define pb push_back
     9 #define lson l,m,rt<<1
    10 #define rson m+1,r,rt<<1|1
    11 #define lch tr[x].son[0]
    12 #define rch tr[x].son[1]
    13 #define max3(a,b,c) max(a,max(b,c))
    14 #define min3(a,b,c) min(a,min(b,c))
    15 typedef pair<int,int> pll;
    16 const int inf = 0x3f3f3f3f;
    17 const LL INF = 0x3f3f3f3f3f3f3f3f;
    18 const LL mod =  (int)1e9+7;
    19 const int N = 1e5 + 100;
    20 int F[N], Finv[N], inv[N];/// F是阶层 Finv是逆元的阶层
    21 void init(){
    22     inv[1] = 1;
    23     for(int i = 2; i < N; i++)
    24         inv[i] = (mod - mod/i) * 1ll * inv[mod % i] % mod;
    25     F[0] = Finv[0] = 1;
    26     for(int i = 1; i < N; i++){
    27         F[i] = F[i-1] * 1ll * i % mod;
    28         Finv[i] = Finv[i-1] * 1ll * inv[i] % mod;
    29     }
    30 }
    31 int comb(int n, int m){ /// C(n,m)
    32     if(m < 0 || m > n) return 0;
    33     return F[n] * 1ll * Finv[n-m] % mod * Finv[m] % mod;
    34 }
    35 int n, m, k, op, x, y;
    36 int dp[55][N];
    37 int add[N];
    38 vector<pll>  vc;
    39 int query(int x){
    40     int ret = dp[k][x];
    41     for(int i = 0; i < vc.size(); i++){
    42         if(vc[i].fi > x) continue;
    43         ret = (ret + 1ll * vc[i].se * comb(k-1+x-vc[i].fi,k-1)) % mod;
    44     }
    45     return ret;
    46 }
    47 void build(){
    48     //memset(add, 0, sizeof(add))
    49     //add[1] += dp[1][1];
    50     for(int i = 0; i < vc.size(); i++){
    51         x = vc[i].fi, y = vc[i].se;
    52         add[x] = (add[x] + y) % mod;
    53     }
    54     vc.clear();
    55     for(int i = 1; i <= n; i++){
    56         dp[1][i] = (dp[1][i-1] + add[i]) % mod;
    57         //add[i] = 0;
    58     }
    59     for(int i = 2; i <= k; i++)
    60         for(int j = 1; j <= n; j++)
    61             dp[i][j] = (dp[i-1][j] + dp[i][j-1]) % mod;
    62 }
    63 int main(){
    64     init();
    65     scanf("%d%d%d", &n, &m, &k);
    66     while(m--){
    67         scanf("%d", &op);
    68         if(op){
    69             scanf("%d", &x);
    70             printf("%d
    ",query(x));
    71         }
    72         else{
    73             scanf("%d%d", &x, &y);
    74             vc.pb(pll(x,y));
    75             if(vc.size() == 2000)
    76                 build();
    77         }
    78     }
    79     return 0;
    80 }
    View Code

      

  • 相关阅读:
    css笔记
    应用软件常用性能数据描述
    软件性能
    对换工作
    微软网络监视器
    神经衰落的治疗方法
    测试工具Loadrunner日志参数的设置与使用 http://epanchen.javaeye.com/blog/317594
    常见的性能测试方法
    web性能测试需要监控IIS的哪些性能指标 http://bbs.51testing.com/thread13221111.html
    应用软件性能数据分类
  • 原文地址:https://www.cnblogs.com/MingSD/p/9528083.html
Copyright © 2011-2022 走看看