poj 3468 A Simple Problem with Integers
来源:互联网 发布:latex windows 10 编辑:程序博客网 时间:2024/06/05 01:59
线段树模板题
#include <stdio.h>#define L(t) ((t) << 1)#define R(t) ((t) << 1 | 1)#define MAXN 100010struct SegTree{ int l,r; long long add, sum; int getMid(){ return ( l + r) >> 1; } int getDis(){ return r - l + 1; }} tree[MAXN << 2];int arr[MAXN];void build(int left, int right, int t){ //递归构造 tree[t].l = left; tree[t].r = right; tree[t].add = 0; if(left == right){ tree[t].sum = arr[left]; //叶结点是数列中的一个数 return; } int mid = tree[t].getMid(); build(left, mid, L(t)); build(mid + 1, right, R(t)); tree[t].sum = tree[L(t)].sum + tree[R(t)].sum; //更新sum}void update(int left, int right, int a, int t){ if( left <= tree[t].l && right >= tree[t].r ){ tree[t].add += a; //若当前子树被目标区间覆盖 更新子树的sum和增量(在本次查询中,增量下行到此为之) tree[t].sum += a * tree[t].getDis(); return; } if( tree[t].add ){ //向子结点传递增量,并更新其sum,最后清空自己的增量 tree[L(t)].sum += tree[L(t)].getDis() * tree[t].add; tree[R(t)].sum += tree[R(t)].getDis() * tree[t].add; tree[L(t)].add += tree[t].add; tree[R(t)].add += tree[t].add; tree[t].add = 0; } int mid = tree[t].getMid(); if(right <= mid ){ update(left, right, a, L(t)); //目标区间仅在左子树上 } else if (left > mid ){ update(left, right, a, R(t)); //目标区间仅在右子树上 } else { update(left, mid, a, L(t)); //目标区间同时在左右子树上 update(mid + 1, right, a, R(t)); } tree[t].sum = tree[L(t)].sum + tree[R(t)].sum ; //更新父结点的sum}long long query(int left, int right, int t){ if(left <= tree[t].l && right >= tree[t].r ){ return tree[t].sum; } if( tree[t].add ){ //这一段和update函数一样,是一个pushDown tree[L(t)].sum += tree[L(t)].getDis() * tree[t].add; tree[R(t)].sum += tree[R(t)].getDis() * tree[t].add; tree[L(t)].add += tree[t].add; tree[R(t)].add += tree[t].add; tree[t].add = 0; } int mid = tree[t].getMid(); if(right <= mid ){ return query(left, right, L(t)); } else if( left > mid ){ return query(left, right, R(t)); } else { return query(left, mid ,L(t)) + query(mid + 1, right, R(t)); }}int main(){ char op[5]; int n, q; scanf("%d%d",&n, &q); for(int i = 1; i <= n; ++i){ scanf("%d",&arr[i]); } build(1, n, 1); int a,b,c; for(int i = 0; i < q; ++i){ scanf("%s ",&op); if(op[0] == 'Q'){ scanf("%d %d",&a, &b); long long sum = query(a, b, 1); printf("%lld\n",sum); } else { scanf("%d %d %d",&a, &b, &c); update(a, b, c, 1); } } return 0;}
此题的数组数组解法很巧妙,可见对于前缀和问题树状数组也是很有效的
见 http://kenby.iteye.com/blog/962159
PS:读入数据不要用long long 会WA的。。。被坑了很久
#include<stdio.h> #define MAXC 100010 long long C[MAXC], D[MAXC], DQ[MAXC]; int A[MAXC];//////////////////树状数组模板 int lowbit(int t) { return t & (t ^ (t - 1)); //计算最小幂 } int add(int i,long long v,int n) { if(n==1) { while(i<=MAXC) //取与C[i]有关的值添上增加的值 { C[i]+=v; i+=lowbit(i); } return 0; }if(n==2) { while(i<=MAXC) { D[i]+=v; i+=lowbit(i); } return 0; }if(n==3) { while(i<=MAXC) { DQ[i]+=v; i+=lowbit(i); } return 0; }return 0;} long long sum(int i,int n) { long long s=0; if(n==1){ while(i>0) //取与C[i]有关的值求和 { s+=C[i]; i-=lowbit(i); } return s; }if(n==2){ while(i>0) { s+=D[i]; i-=lowbit(i); } return s; }if(n==3){ while(i>0) { s+=DQ[i]; i-=lowbit(i); } return s; }return 0;} //////////////////树状数组模板 int main(){ char op[5]; int n, q; scanf("%d%d",&n, &q); for(int i = 1; i <= n; ++i){ scanf("%d",&A[i]); add(i,A[i],1); } int a,b,c; for(int i = 0; i < q; ++i){ scanf("%s ",&op); if(op[0] == 'Q'){ scanf("%d %d",&a, &b); long long ss =( sum(b,1) + (b+1)*sum(b,2) - sum(b,3) ) - ( sum(a-1,1) + (a)*sum(a-1,2) - sum(a-1,3) ); printf("%lld\n",ss); } else { scanf("%d %d %d",&a, &b, &c); add(a,c,2);add(b+1,-c,2);add(a,c*a,3); add(b+1,-c*(b+1),3); } } return 0; }
- POJ 3468 A Simple Problem With Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ-3468-A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 - A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- 想学编程?这样开始
- 使用 Xcode 在越狱 iOS 设备上进行开发调试
- 安装LoadRunner时出现“计算机缺少vc2005_sp1_with_atl_fix_redist”的解决办法
- Oracle触发器4-数据库事件触发器
- 智能指针(指向转移写法)
- poj 3468 A Simple Problem with Integers
- 多线程统计多个文件的单词数目
- QT学习(三)
- 智能指针(引用计数版)
- JAVA程序退出时执行的操作Runtime类的addShutdownHook函数使用示例
- ATPCS
- [20130408]001—.Net开选择WEBFORM还是MVC
- Java Process中waitFor()的问题
- 专访蒋彪:JavaEE是企业级开发首选