zoukankan      html  css  js  c++  java
  • UESTC_秋实大哥与花 2015 UESTC Training for Data Structures<Problem B>

    B - 秋实大哥与花

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
     

    秋实大哥是一个儒雅之人,昼听笙歌夜醉眠,若非月下即花前。

    所以秋实大哥精心照料了很多花朵。现在所有的花朵排成了一行,每朵花有一个愉悦值。

    秋实大哥每天要对着某一段连续的花朵歌唱,然后这些花朵的愉悦值都会增加一个相同的值v(v可能为负)。

    同时他想知道每次他唱完歌后这一段连续的花朵的愉悦值总和是多少。

    Input

    第一行有一个整数n,表示花朵的总数目。

    第二行包含n个整数ai,表示第i朵花初始的愉悦值。

    第三行包含一个整数m,表示秋实大哥唱了m天的歌。

    接下来m行,每行包含三个整数l r v,表示秋实大哥对着[l,r]这个区间内的花朵歌唱,每朵花的愉悦值增加了v

    1nmai|v|1000001lrn

    Output

    输出共m行,第i行表示秋实大哥完成第i天的歌唱后,那一段花朵的愉悦值总和。

    Sample input and output

    Sample InputSample Output
    3
    0 0 0
    3
    1 2 1
    1 2 -1
    1 3 1
    2
    0
    3

    解题报告:

    没啥好说的,线段树模板基础题。。唯一需要注意的就是long long了.

    当然我是使用的树状数组:

    题目中操作属于区间更新 - 区间查询<查询点也是区间嘛>类型,可使用树状数组来实现.

    令C[i]为从1至i号花的共同更新之和.

    首先考虑更新,add[l,r,v] → c[r] += v , c[l-1] -=v;

     Sum[x] = 从 1 至 x 号花的value之和.

      Sum[x] = c[1]*1 + c[2]*2 + c[3] * 3 ..... + c[x] * x + (c[x+1] + .... C[n] ) *x;

              = (segema)f(x) + (segema)g(x) * x;

              = 两个树状数组,一个维护 c[i]*i ,一个维护c[i]

    之后考虑区间查询:

     Query(l , r)

     = sum[r] - sum[l-1]

     1 #include <iostream>
     2 #include <cstring>
     3 typedef long long ll;
     4 using namespace std;
     5 const int maxn = 1e5 + 50;
     6 ll n;
     7 ll f[maxn],g[maxn];
     8 
     9 
    10 inline ll lowbit(ll idx)
    11 {
    12     return idx & (-idx);
    13 }
    14 
    15 void updataf(ll idx,ll res)
    16 {
    17     if (!idx)
    18      return;
    19     while(idx <= n)
    20      {
    21          f[idx] += res;
    22          idx += lowbit(idx);
    23      }
    24 }
    25 
    26 void updatag(ll idx,ll res)
    27 {
    28     if (!idx)
    29      return;
    30     while(idx <= n)
    31      {
    32          g[idx] += res;
    33          idx += lowbit(idx);
    34      }
    35 }
    36 
    37 ll sumf(ll idx)
    38 {
    39     ll res = 0;
    40     while(idx > 0)
    41      {
    42          res += f[idx];
    43          idx -= lowbit(idx);
    44      }
    45     return res;
    46 }
    47 
    48 ll sumg(ll idx)
    49 {
    50     ll res = 0;
    51     while(idx > 0)
    52      {
    53          res += g[idx];
    54          idx -= lowbit(idx);
    55      }
    56     return res;
    57 }
    58 
    59 int main(int argc,char *argv[])
    60 {
    61   ll m;
    62   scanf("%lld%lld",&n,&m);
    63   memset(f,0,sizeof(f));
    64   memset(g,0,sizeof(g));
    65   for(int j = 1 ; j <= n ; ++ j)
    66    {
    67          ll v;
    68          scanf("%lld",&v);
    69          updataf(j,v*j);
    70          updataf(j-1,-v*(j-1));
    71          updatag(j,v);
    72          updatag(j-1,-v);
    73    }
    74   while(m--)
    75    {
    76          ll i,j,v;
    77          scanf("%lld%lld%lld",&i,&j,&v);
    78          updataf(j,v*j);
    79          updataf(i-1,-v*(i-1));
    80          updatag(j,v);
    81          updatag(i-1,-v);
    82          i--;
    83          ll res1 = sumf(i) + i*(sumg(n)-sumg(i));
    84       ll res2 = sumf(j) + j*(sumg(n)-sumg(j));
    85          printf("%lld
    ",res2 - res1);
    86    }
    87   return 0;
    88 }

     

    No Pain , No Gain.
  • 相关阅读:
    Java字符串跟ASCII码互转
    java 一款可以与ssm框架完美整合的web报表控件
    使用<c:set>标签配置项目路径
    Linux下部署tomcat及tomcat war包应用程序
    支付宝app支付服务端流程
    文本数据增量导入到mysql
    java 读取mysql中数据 并取出
    实现读取文本数据,在将数据导入mysql
    给一个整形数组,给出一个值,当这个值是数组某些数字的和,求出数组下标的值
    文本数据和mysql 里面的数据比较
  • 原文地址:https://www.cnblogs.com/Xiper/p/4470205.html
Copyright © 2011-2022 走看看