POJ -3468- A Simple Problem with Integers (线段是区间修改)
来源:互联网 发布:vscode js代码提示 编辑:程序博客网 时间:2024/06/07 15:38
A Simple Problem with Integers
区间更新问题(题目链接)
这道题不同于更新单点,更新单点时间复杂度是log(n)
但是如果是区间更新就是nlog(n)
这样的处理方式是有悖于线段树的宗旨
那么如何解决?
单点更新的问题在于必须具体更新到每一个数
比如 更新区间 1 - 9 那么必须更新1-9的值。
如果可以不用更新1-9的值,那么时间复杂度至少减少一半
那么我们就在结构体里面新加一项,区间增值
如果一个区间在需要更新的区间里,那么它的子区间都需要更新,需要加上增加值
如果我们在更新的时候的时候把子区间都列出来更新了是非常费时的
那么当发现这类区间的时候,我们把区间的增加值记录在这个区间中
当查询下面的小区间时,看看上面的区间是不是有增加值,如果有,那么加上
AC代码
#include<stdio.h>#include<algorithm>#include<iostream>using namespace std;const int MAXN=100000;int num[MAXN];struct Node{ int l,r;//区间的左右端点long long nSum;//区间上的和long long Inc;//区间增量的累加}segTree[MAXN*3];void Build(int i,int l,int r){ segTree[i].l=l; segTree[i].r=r; segTree[i].Inc=0; if(l==r) { segTree[i].nSum=num[l]; return; } int mid=(l+r)>>1; Build(i<<1,l,mid); Build(i<<1|1,mid+1,r); segTree[i].nSum=segTree[i<<1].nSum+segTree[i<<1|1].nSum;}void Add(int i,int a,int b,long long c)//在结点i的区间(a,b)上增加c{ if(segTree[i].l==a&&segTree[i].r==b)//如果区间相等重合 { segTree[i].Inc+=c; //加到区间增量上 return; } segTree[i].nSum+=c*(b-a+1);//区间加上区间增量(从头到尾的增量) int mid=(segTree[i].l+segTree[i].r)>>1; if(b<=mid) Add(i<<1,a,b,c);//缩小l r的区间 else if(a>mid) Add(i<<1|1,a,b,c); else//缩小a,b的区间 { Add(i<<1,a,mid,c); Add(i<<1|1,mid+1,b,c); }}long long Query(int i,int a,int b)//查询a-b的总和{ if(segTree[i].l==a&&segTree[i].r==b) { return segTree[i].nSum+(b-a+1)*segTree[i].Inc; } segTree[i].nSum+=(segTree[i].r-segTree[i].l+1)*segTree[i].Inc; int mid=(segTree[i].l+segTree[i].r)>>1; Add(i<<1,segTree[i].l,mid,segTree[i].Inc); Add(i<<1|1,mid+1,segTree[i].r,segTree[i].Inc); segTree[i].Inc=0; if(b<=mid) return Query(i<<1,a,b); else if(a>mid) return Query(i<<1|1,a,b); else return Query(i<<1,a,mid)+Query(i<<1|1,mid+1,b);}int main(){ int n,q; int i; int a,b,c; char ch; while(scanf("%d%d",&n,&q)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&num[i]); Build(1,1,n); for(i=1;i<=q;i++) { cin>>ch; if(ch=='C') { scanf("%d%d%d",&a,&b,&c); Add(1,a,b,c); } else { scanf("%d%d",&a,&b);fff printf("%I64d\n",Query(1,a,b)); } } } return 0;}
阅读全文
0 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 3468A 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(线段树区间修改)
- 七种重要的模型验证错误矩阵
- 正式开始写自己的博客
- AVL树
- Java内部类的使用小结
- hdu 1867 kmp A + B for you again
- POJ -3468- A Simple Problem with Integers (线段是区间修改)
- 负载均衡,反向代理,集群解释
- 如何生成Https请求需要的bks证书
- 解决wordpress wp-conten没有权限的问题
- 最长公共子序列问题(LCS)
- SqlServer批量压缩数据库日志-多数据库批量作业,批量备份还原
- ConnectivityManager判断当前网络连接类型,非WiFi网络流量加载模式
- 包含关键字 jeesite 的文章-1
- Java 内存模型与线程