poj3468 A Simple Problem with Integers
题意:O(-1)
思路:O(-1)
题意:O(-1)
思路:O(-1)
线段树功能:update:成段增减 query:区间求和
Sample Input
10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4
Sample Output
4 55 9 15
Hint
The sums may exceed the range of 32-bit integers.
题目大意:
N个数 M个操作 每个操作分Q a b得区间(a,b)的和;C a b c 区间[a,b]里面每个元素的value加c
由于是成段更新 要用到延迟标记type; 每次C操作 只更新到和某个节点的区间范围一致,下次在访问的时候 延迟标记下移
#include <cstdio> #include <algorithm> using namespace std; #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const int maxn = 111111; struct Tree{ __int64 value; __int64 type; }tree[maxn<<2]; void PushUp(int rt) { tree[rt].value = tree[rt<<1].value + tree[rt<<1|1].value; } void PushDown(int rt,int ms) { if (tree[rt].type) { tree[rt<<1].type += tree[rt].type; tree[rt<<1|1].type += tree[rt].type ; tree[rt<<1].value += (ms - (ms >> 1)) * tree[rt].type; tree[rt<<1|1].value += (ms >> 1) * tree[rt].type; tree[rt].type = 0; } } void build(int l,int r,int rt) { tree[rt].type=0; __int64 val; if (l == r){ scanf("%I64d",&val); tree[rt].value=val; return ; } int m = (l + r) >> 1; build(lson); build(rson); PushUp(rt); } void update(int L,int R,int c,int l,int r,int rt) { if (L <= l && r <= R) {//标记1 //更新到这就行,不一定更新到最底端 tree[rt].type += c; tree[rt].value += c * (r - l + 1); return ; } PushDown(rt , r - l + 1);//延迟标记,这时候后推, (标记2) //比如建了 [1,4] 然后我们第一次的时候是更新[1,2] // [1,2][3,4] [1,2]的type就是非0,value往上更新; // [1][2][3][4] 第二次如果还是要更新[1,2] 在标记1直接更新 int m = (l + r) >> 1; // 而如果你是要更新[1,1](必定访问到标记2) 那么先进行标记2 让两儿子的value更新 if (L <= m) update(L , R , c , lson); //记得这时候儿子type被赋值,自己type=0; if (R > m) update(L , R , c , rson); PushUp(rt); } __int64 query(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { return tree[rt].value; } PushDown(rt , r - l + 1); //注意这里 int m = (l + r) >> 1; //如果之前标记[1,4]type!=0 然后我们现在 __int64 ret = 0; //如果是访问[1,4]第一步直接得到返回值是没有问题 if (L <= m) ret += query(L , R , lson); //但访问[1,3]的时候要要把之前的[1,4]延迟标记下移 if (R > m) ret += query(L , R , rson); return ret; } int main() { int N , Q; scanf("%d%d",&N,&Q); build(1 , N , 1); while (Q --) { char op[2]; int a , b , c; scanf("%s",op); //防止用%c 会接受回车 新技能get√ if (op[0] == 'Q') { scanf("%d%d",&a,&b); printf("%lld\n",query(a , b , 1 , N , 1)); } else { scanf("%d%d%d",&a,&b,&c); update(a , b , c , 1 , N , 1); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
today lazy . tomorrow die .