九度1407(线段树+延迟更新)
来源:互联网 发布:单片机交通灯控制系统 编辑:程序博客网 时间:2024/05/17 23:16
给定一个大小为N 的整数数组array,我们定义两种操作:
<!--[if !supportLists]-->1) <!--[endif]-->Add(L, R, W)。即将子数组[L, R]中的元素,都累加一个整数W。
<!--[if !supportLists]-->2) <!--[endif]-->Min(L, R)。即返回子数组[L, R]之中,最小的一个元素的值。
其中L和R为数组的下标,且从0开始计数。当数组下标L > R时,我们认为这个子数组的元素包含array[L], array[L+1], … array[N – 1], array[0], array[1], … array[R]。
- 输入:
每个测试文件包含多个测试案例。
每个测试案例的第一行为整数N, 其中1 <= N <= 100000, 表示数组array的元素个数。
第二行将会输入N个数组元素a1, a2,… an,且-10^6 <= ai <= 10^6。
第三行将输入整数M,其中 100000 <= M <= 100000,代表接下来将会输入的操作数
余下的M行将会是具体的对数组的操作指令:若一行中含有3个整数参数,则该操作为Add操作,需要对array的元素进行更新操作,三个参数依次代表L, R以及W;若一行中只有两个参数,则该操作为Min操作,你需要返回当前子数组[L, R]之中最小的元素大小。对于所有的操作指令, 都满足0 <= L, R <= N – 1, -10^6 <= W <= 10^6。
- 输出:
对于每个测试案例中的所有Min操作,都返回其指定的操作值。
- 样例输入:
31 2 430 20 0 10 2
- 样例输出:
12
本题属于线段树在区间上修改、查询,应使用线段树的延迟更新算法
设置结构体struct node{ int L,R; long long int Min; long long int w; node *left,*right;};
其中Min表示该区间最小值,w表示该区间的加因子
当需修改某段区间时并不修改到根节点(避免超时),而是滞留在某些小区间上(这些小区间的和等于需修改区间),记住及时修改路径上的Min
当需查询某段区间时则一顺把该路径上的w依次往下推,直到找到需查询区间为止
#include<iostream>#include<cstring>#include<string>#include<cstdio>using namespace std;const long long int nMin=1<<30;struct node{ int L,R; long long int Min;//记录该区间最小值 long long int w;//记录该区间加因子 node *left,*right;};node tree[100000*2+10];int co;void Build(node *root,int a,int b)//建立一颗线段树,初始化{ root->L=a; root->R=b; root->w=0; root->Min=nMin; if(a!=b) { co++; root->left=tree+co; co++; root->right=tree+co; Build(root->left,a,(root->L+root->R)/2); Build(root->right,(root->L+root->R)/2+1,b); }}long long min(long long a,long long b){ if(a<b) return a; else return b;}void insert(node *root,int i,long long int s)//依次插入元素{ if(root->L==i&&root->R==i) { root->Min=s; return; } if(i<=(root->L+root->R)/2)insert(root->left,i,s); elseinsert(root->right,i,s); root->Min=min(root->Min,s);}void Add(node *root,int a,int b,long long int s)//线段树的延迟更新{ if(root->L==a&&root->R==b){root->w+=s;return ;} if(b<=(root->L+root->R)/2) { Add(root->left,a,b,s); } else if(a>=(root->L+root->R)/2+1) { Add(root->right,a,b,s); } else { Add(root->left,a,(root->L+root->R)/2,s); Add(root->right,(root->L+root->R)/2+1,b,s); }//root->Min=min(root->right->Min,root->left->Min);root->Min=min(root->right->Min+root->right->w,root->left->Min+root->left->w);}long long Query(node *root,int a,int b)//查询{ if(root->L==a&&root->R==b) { return root->Min+root->w; } if(root->w!=0) { Add(root->left,root->L,(root->L+root->R)/2,root->w);Add(root->right,(root->L+root->R)/2+1,root->R,root->w); } root->Min+=root->w; root->w=0; if(b<=(root->L+root->R)/2)return Query(root->left,a,b); else if(a>=(root->L+root->R)/2+1)return Query(root->right,a,b); else { return min(Query(root->left,a,(root->L+root->R)/2), Query(root->right,(root->L+root->R)/2+1,b)); }}int main(){ int j,i;long long int k; int n,m; int x,y; long long int z; char c; while(scanf("%d",&n)!=EOF) { co=0; Build(tree,1,n); for(i=1;i<=n;i++) {scanf("%lld",&k);insert(tree,i,k); } cin>>m; for(i=0;i<m;i++) {cin>>x>>y;c=getchar();if(c!='\n'){scanf("%lld",&z);if(x<=y)Add(tree,x+1,y+1,z);else{Add(tree,x+1,n,z);Add(tree,1,y+1,z);}}else{long long num;if(x<=y)num=Query(tree,x+1,y+1);else{num=min(Query(tree,x+1,n),Query(tree,1,y+1));}printf("%lld\n",num);} } } return 0;}
- 九度1407(线段树+延迟更新)
- hdu3954 线段树延迟更新
- POJ3468(线段树+延迟更新)
- poj4047(线段树+延迟更新)
- poj2777(延迟更新+线段树)
- 【线段树延迟更新】HDU 3275
- poj 3468线段树延迟更新
- 线段树区间更新延迟标记
- poj3468 线段树+延迟更新
- 线段树(4)--poj3468(区间更新 延迟更新)
- 线段树(成段更新 关于延迟标记) poj3468
- 【线段树延迟更新】Codeforces Round #104 (Div. 1) E
- zoj 1610 Count the Colors(线段树延迟更新)
- poj2777 Count Color线段树延迟更新,二进制状态记录
- hdu 1556 线段树区间延迟更新好题
- hdu 5023 线段树延迟更新+状态压缩
- 线段树区间更新模板(lazy延迟标记)(1698)
- poj3667 Hotel 线段树延迟更新 区间合并
- Android开发之Eclipse快捷键大全
- 常用的正则表达式
- 关于Arduino图形化编程插件ArduBlock的安装方法
- POJ 3125 Printer Queue 模拟队列
- mysql学习总结一当数据不存在的时候插入,存在的时候进行更新,删除重复数据
- 九度1407(线段树+延迟更新)
- MyEclipse更改SVN更新地址
- 循序渐进DB2(第2版)——DBA系统管理、运维与应用案例
- QQ web api
- 红黑树(插入)
- 红黑树(删除)
- C++中为什么要设置缓冲区
- struts2对ognl表达式的使用(配图解加讲解)
- 深入理解PHP内核