boj 451 田田的算数题 区间更新树状数组

题目链接:http://code.bupt.edu.cn/problem/p/451/

区间加上一个等差数列

这里涉及i的二次项

具体的做法见上一篇博文

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
#include <map>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const ull B = 9973;
const int maxn = 110000;
const ll M = 23333;

ll bit0[maxn];
ll bit1[maxn];
ll bit2[maxn];

int n, q;

ll sum(ll *b, int i)
{
    ll s = 0;
    while(i > 0)
    {
        s += b[i];
        i -= i & -i;
    }
    return s;
}

void add(ll *b, int i, ll v)
{
    while(i <= n)
    {
        b[i] += v;
        i += i & -i;
    }
}

int main()
{
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif

    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &q);
        memset(bit0, 0, sizeof(bit0));
        memset(bit1, 0, sizeof(bit1));
        memset(bit2, 0, sizeof(bit2));

        for(int i = 1; i <= n; i++)
        {
            int t;
            scanf("%d", &t);
            add(bit0, i, (ll)2*t);
        }

        for(int i = 0; i < q; i++)
        {
            int mode;
            scanf("%d", &mode);
            if(mode == 1)
            {
                int l, r, x, d;
                scanf("%d%d%d%d", &l, &r, &x, &d);
                add(bit0, l, (ll)(-(ll)d*(l-1)*(l-1)-((ll)(2*x+d-2*l*d)*(l-1))));
                add(bit1, l, (ll)(2*x+d-2*l*d));
                add(bit2, l, (ll)d);
                add(bit0, r+1, (ll)((ll)d*r*r+(ll)(2*x+d-2*l*d)*r));
                add(bit1, r+1, (ll)(-(2*x+d-2*l*d)));
                add(bit2, r+1, (ll)(-d));
            }
            else
            {
                int l, r;
                scanf("%d%d", &l, &r);
                ll res = 0;
                res += sum(bit0, r) + sum(bit1, r)*r + sum(bit2, r)*r*r;
                res -= sum(bit0, l-1) + sum(bit1, l-1)*(l-1) + sum(bit2, l-1)*(l-1)*(l-1);
                printf("%lld\n", res/2);
            }
        }

    }

    return 0;
}
时间: 2024-10-05 04:45:08

boj 451 田田的算数题 区间更新树状数组的相关文章

51nod_1199 树的先跟遍历+区间更新树状数组

题目是中文,所以不讲题意 做法顺序如下: 使用先跟遍历,把整棵树平铺到一维平面中 使用自己整的区间更新树状数组模板进行相关操作. http://www.cnblogs.com/rikka/p/7359185.html 放代码如下: 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 6 /* 7 *常量MAXN用于设定树状数组的尺寸大小 8 */ 9 const long long MAXN=500233; 10 class TreeL

BZOJ 2683 简单题 cdq分治+树状数组

题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后,二维的数据结构是显然不能过的,于是我们可能会考虑把一维排序之后另一位上数据结构什么的,然而cdq分治却能够很好的体现它的作用. 首先,对于每一个询问求和,显然是x在它左边的并且出现时间在它之前的所有的change对他可能会有影响. 我们按照x第一关键字,y第二关键字,操作第三关键字来排序所有的询问,然后在cdq的时候,每次递归处理左半区间,按照x动态的将y这一列的值加到树状数组里,来更新右半边的所有询问,注意这

树状数组求区间最大值(树状数组)(复习)

如题. 当遇到单点更新时,树状数组往往比线段树更实用. 算法: 设原数序列为a[i],最大值为h[i](树状数组). 1.单点更新: 直接更新a[i],然后再更新h[i].若h[i]的值有可能改变的,则表示区间一定包含i结点.那么就两层lowbit更新所有可能的h. 单点更新时间复杂度O(logn*logn) 1 void update(int x) 2 { 3 while(x<=n) 4 { 5 h[x]=a[x]; 6 for(int i=1;i<lowbit(x);i<<=1

【BZOJ3132】上帝造题的七分钟 树状数组

[BZOJ3132]上帝造题的七分钟 Description “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. 第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作. 第四分钟,彩虹喵说,要基于二叉树的数据结构,于是便有了数据范围. 第五分钟,和雪说,要有耐心,于是便有了时间限制. 第六分钟,吃钢琴男说,要省点事,于是便有了保证运算过程中

线段树(单点更新)/树状数组 HDOJ 1166 敌兵布阵

题目传送门 1 /* 2 线段树基本功能:区间值的和,修改某个值 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #define lson l, m, rt << 1 7 #define rson m+1, r, rt << 1|1 8 9 const int MAX_N = 50000 + 10; 10 int sum[MAX_N<<2]; 11 12 void pushup(int rt) //

POJ 2481 树状数组 区间覆盖(POJ2352 Stars 的变形题)(线段化点)

0)学会将题目情景转化为自己熟悉的结构或模型. 题目大意: 每个奶牛有自己的一个区间,求每个奶牛的区间所覆盖的子区间个数(注意,真子集,相等的不算),按照输入的顺序输出. 转化: 要学会将题目情景转化为自己熟悉的模型或结构上.把每个区间的左端x值作为点的x坐标,右端x值作为点的y坐标,就可以把所有区间转化为一个二维坐标图上的点集,而此时每个点左上方的点(同Stars那道题目一样不包括自身)的个数,就是每个区间所覆盖的子区间的个数(对应题目要求,这里或许可以再变形). 同POJ2481 Stars

区间素数个数 树状数组 HIT 1867 经理的烦恼

http://acm.hit.edu.cn/hoj/problem/view?id=1867 经理的烦恼   Source : HCPC 2005 Spring   Time limit : 2 sec   Memory limit : 32 M Submitted : 2994, Accepted : 686 Jerry是一家公司销售部门的经理.这家公司有很多连锁店,编号为1,2,3,... Jerry每天必须关注每家连锁店的商品数量及其变化,一项很乏味的工作.在连锁店比较少的时候,Jerry

HDU 6447 - YJJ&#39;s Salesman - [树状数组优化DP][2018CCPC网络选拔赛第10题]

Problem DescriptionYJJ is a salesman who has traveled through western country. YJJ is always on journey. Either is he at the destination, or on the way to destination.One day, he is going to travel from city A to southeastern city B. Let us assume th

hdu 4970 树状数组区间更新 思维题

http://acm.hdu.edu.cn/showproblem.php?pid=4970 好像还没有用树状数组写过区间更新,但是树状数组的确比线段树快很多,不知道跟ZKW线段树比效率怎么样: 先贴个模板: #include <cstdio> const int MAXN = 1024; int B[MAXN], C[MAXN]; #define LOWBIT(x) ((x)&(-(x))) void bit_update(int *a, int p, int d) { for (