poj 3468【线段树+延迟优化】
来源:互联网 发布:java 下载图片到本地 编辑:程序博客网 时间:2024/06/07 15:46
经典线段树题目,如果用一般的深入到每个节点去修改值的方法会TLE,所以这里引入一个新名词“延迟优化”,意思是说每个节点线段有一个增量值inc,用来保存增量的,当当前区间等于要查询的区间就用当前区间的和sum+当前区间的增量inc*(t-s+1),否则就把增量传下去,而当前区间则加上这增量和并且inc 归零
由于此时poj突然没有了这题,估计要改数据,所以提交不了,先上代码。
线段树
Accepted7116K1688MSC++int lowbit(int t){return t&(-t);}int countbit(int t){return (t==0)?0:(1+countbit(t&(t-1)));}int gcd(int a,int b){return (b==0)?a:gcd(b,a%b);}#define LL long long#define pi acos(-1)#define N 100010#define INF INT_MAX#define eps 1e-8struct node{ int l,r; LL sum; LL inc;}c[N*4];LL a[N];int n,m;void Build(int i,int s,int t){ c[i].l=s; c[i].r=t; c[i].inc=0; if(s==t) { c[i].sum=a[s];//printf("!%I64d\n",a[i]); return ; } if(s<t){ int mid=(s+t)>>1; Build(2*i,s,mid); Build(2*i+1,mid+1,t); } c[i].sum=c[2*i].sum+c[2*i+1].sum;}void add(int i,int s,int t,LL num){ if(c[i].l==s && c[i].r==t) { c[i].inc+=num; return ; } c[i].sum+=(t-s+1)*num; int mid=(c[i].l+c[i].r)>>1; if(t<=mid) add(2*i,s,t,num); else if(mid<s) add(2*i+1,s,t,num); else { add(2*i,s,mid,num); add(2*i+1,mid+1,t,num); }}LL query(int i,int s,int t){ LL del=c[i].inc; if(c[i].l==s && c[i].r==t) { return c[i].sum+del*(t-s+1); } else// { c[2*i].inc+=c[i].inc; c[2*i+1].inc+=c[i].inc; c[i].sum+=del*(c[i].r-c[i].l+1);//!!! c[i].inc=0; } int mid=(c[i].l+c[i].r)>>1; if(t<=mid) return query(2*i,s,t); else if(mid<s) return query(2*i+1,s,t); else { return query(2*i,s,mid) + query(2*i+1,mid+1,t); }}int main(){ //freopen("a.txt","r",stdin); int i,j; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=n;i++) scanf("%I64d",&a[i]); Build(1,1,n); while(m--) { char str[3]; int s,t; scanf("%s %d %d",str,&s,&t); if(str[0]=='Q') { LL ans=query(1,s,t); printf("%I64d\n",ans); } else { LL d; scanf("%I64d",&d); add(1,s,t,d); } } } return 0;}
树状数组:
Accepted2876K1141MSC++1883Bint lowbit(int t){return t&(-t);}int countbit(int t){return (t==0)?0:(1+countbit(t&(t-1)));}int gcd(int a,int b){return (b==0)?a:gcd(b,a%b);}#define LL long long#define pi acos(-1)#define N 100010#define INF INT_MAX#define eps 1e-8LL c1[N]; /* 维护delta[i]的前缀和 */LL c2[N]; /* 维护delta[i]*i的前缀和 */LL sum[N];int a[N];int n;LL query(LL *array, int i){ LL tmp; tmp = 0; while (i > 0) { tmp += array[i]; i -= lowbit(i); } return tmp;}void add(LL *array, int i, LL d){ while (i <= n) { array[i] += d; i += lowbit(i); }}int main(){ //freopen("a.txt","r",stdin); int m, i; LL ans; char str[3]; while(scanf("%d %d", &n, &m)!=EOF) { for (i = 1; i <= n; i++) scanf("%d", &a[i]); for (i = 1; i <= n; i++) sum[i] = sum[i-1] + a[i]; while (m--) { scanf("%s",str); LL s,t,d; scanf("%I64d%I64d",&s,&t); if (str[0] == 'Q') { ans = sum[t] - sum[s-1]; ans += (t+1)*query(c1, t) - query(c2, t); ans -= s*query(c1, s-1) - query(c2, s-1); printf("%I64d\n", ans); } else { scanf("%I64d", &d); add(c1, s, d); add(c1, t+1, -d); add(c2, s, d*s); add(c2, t+1, -d*(t+1)); } } } return 0;}
- poj 3468【线段树+延迟优化】
- poj 3468线段树延迟更新
- poj 3468 线段树,延迟标记法
- poj 3468 线段树延迟标记
- 线段树模板 (poj 3468)延迟标记
- POJ 3277 线段树 + 延迟标记
- C - A Simple Problem with Integers POJ 3468(线段树+延迟标记)
- 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(线段树 + Lazy Tag(延迟更新))
- POJ 3468 A Simple Problem with Integers(线段树,延迟标记)
- POJ 3667 线段树 + 延迟标记 + 区间处理
- POJ 3667 Hotel(线段树+区间合并+延迟标记)
- POJ 2528 线段树 + 延迟标记 + 离散化
- POJ 2528 线段树(离散化+延迟标记)
- freeswitch 内核研究笔记 (持续更新)
- 系统托盘中的快捷图标
- Google Chrome 的内核引擎 WebKit 介绍
- 庆祝开博,献上IAR for arm 6.10
- 再次理解保护模式特权级——CPL、DPL、RPL、数据段、堆栈段、一致代码段、非一致代码段
- poj 3468【线段树+延迟优化】
- HDU3551 一般图最大匹配
- 关于MAP文件的使用(转贴)
- Delphi操作Excel大全
- linux C语言 杀死进程方式
- hdu 3911 Black And White
- 代码添加ProgressBar 进度条
- 符号链接与path路径的区别?
- mysql知识积累(三)常用