[线段树] poj3468 A Simple Problem with Integers
2015-07-29 14:58
288 查看
重新把以前的线段树内容写了一遍,线段树的熟悉程度还要继续加强
具体的分析可以看这里~
poj3468题解
具体的分析可以看这里~
poj3468题解
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; int T,n,m,num,a,b,SUM,MAXV; struct node { int L,R; long long nSum; //原来的求和 long long Inc; //区间更新的延迟累加 int mid() { return (L+R)/2; } } tree[400010]; int nCount = 0; void build(int root,int L,int R) { tree[root].L = L; tree[root].R = R; tree[root].nSum = 0; tree[root].Inc = 0; if(L==R) return; else { build(root*2,L,(L+R)/2); build(root*2+1,(L+R)/2+1,R); } } void insert(int root,int i,int v) { if (tree[root].L ==tree[root].R) { tree[root].nSum = v; return ; } tree[root].nSum += v; if (i<=tree[root].mid()) insert(root*2,i,v); else insert(root*2+1,i,v); } //对a~b范围内的每一个数都加c void RangeAdd(int root,int a,int b,long long c) { if (tree[root].L==a && tree[root].R ==b) { tree[root].Inc += c; return; } tree[root].nSum += c*(b-a+1); if( b <= tree[root].mid()) RangeAdd(root*2,a,b,c); else if (a >=tree[root].mid()+1 ) RangeAdd(root*2+1,a,b,c); else { RangeAdd(root*2,a,tree[root].mid(),c); RangeAdd(root*2+1,tree[root].mid()+1,b,c); } } long long querynSum(int root,int a,int b) { if (tree[root].L ==a && tree[root].R==b) { return tree[root].nSum + (tree[root].R - tree[root].L + 1) * tree[root].Inc; } tree[root].nSum += (tree[root].R - tree[root].L +1)*tree[root].Inc; RangeAdd(root*2,tree[root].L,tree[root].mid(),tree[root].Inc); RangeAdd(root*2+1,tree[root].mid()+1,tree[root].R,tree[root].Inc); tree[root].Inc = 0; if ( b <= tree[root].mid() ) return querynSum(root*2,a,b); else if (a > tree[root].mid()) return querynSum(root*2+1,a,b); else { return querynSum(root*2,a,tree[root].mid()) + querynSum(root*2+1,tree[root].mid()+1,b); } } int main() { //freopen("in.txt","r",stdin); int n,q,a,b,c; char cmd[10]; scanf("%d%d",&n,&q); int i; nCount = 0; build(1,1,n); for( i = 1; i <= n; i ++ ) { scanf("%d",&a); insert(1,i,a); } for( i = 0; i < q; i ++ ) { scanf("%s",cmd); if ( cmd[0] == 'C' ) { scanf("%d%d%d",&a,&b,&c); RangeAdd(1,a,b,c); } else { scanf("%d%d",&a,&b); printf("%I64d\n",querynSum(1,a,b)); } } return 0; }
相关文章推荐
- windows上安装Mongodb提示主机拒绝
- Map接口的使用注意事项
- 解决IE下a标签点击有虚线边框的问题
- uva10051(dp 立方体塔, 拆分)
- python 进行Web接口测试实战
- Putty设置自己主动两次登录
- GCD基本使用
- html meta标签常用属性整理
- ecshop购买了某商品才能评价且只能评价一次
- 3.网上解决org.apache.commons.lang.xwork.StringUtils的方法都弱爆了,看我怎么解决它!
- ASP.NET数据库连接字符串
- PIL “The _imagingft C module is not installed” 错误补救
- appium-3 事件
- XSI IPC机制
- ExtJs 4.2 TabCloseMenu.js的Bug
- C#两路list数组归并去重
- Windows多线程同步系列之二-----关键区
- 如何将资源id转换为Uri,适用于Fresco.setImageURI();
- php调用淘宝开放API实现根据卖家昵称获取卖家店铺ID的方法
- android 实现分享功能