CodeForces 52C Circular RMQ(间隔周期段树,间隔更新,间隔总和)
2015-07-23 13:50
471 查看
转载请注明出处:http://blog.csdn.net/u012860063
题目链接:http://codeforces.com/problemset/problem/52/C
You are given circular array a0, a1, ..., an - 1.
There are two types of operations with it:
inc(lf, rg, v) — this operation increases each element on the segment [lf, rg] (inclusively)
by v;
rmq(lf, rg) — this operation returns minimal value on the segment [lf, rg] (inclusively).
Assume segments to be circular, so if n = 5 and lf = 3, rg = 1,
it means the index sequence: 3, 4, 0, 1.
Write program to process given sequence of operations.
Input
The first line contains integer n (1 ≤ n ≤ 200000).
The next line contains initial state of the array: a0, a1, ..., an - 1 ( - 106 ≤ ai ≤ 106),ai are
integer. The third line contains integer m (0 ≤ m ≤ 200000), m —
the number of operartons. Next m lines contain one operation each. If line contains two integer lf, rg (0 ≤ lf, rg ≤ n - 1)
it means rmq operation, it contains three integers lf, rg, v (0 ≤ lf, rg ≤ n - 1; - 106 ≤ v ≤ 106)
— inc operation.
Output
For each rmq operation write result for it. Please, do not use %lld specificator
to read or write 64-bit integers in C++. It is preffered to use cout (also you may use %I64d).
Sample test(s)
input
output
代码例如以下:
题目链接:http://codeforces.com/problemset/problem/52/C
You are given circular array a0, a1, ..., an - 1.
There are two types of operations with it:
inc(lf, rg, v) — this operation increases each element on the segment [lf, rg] (inclusively)
by v;
rmq(lf, rg) — this operation returns minimal value on the segment [lf, rg] (inclusively).
Assume segments to be circular, so if n = 5 and lf = 3, rg = 1,
it means the index sequence: 3, 4, 0, 1.
Write program to process given sequence of operations.
Input
The first line contains integer n (1 ≤ n ≤ 200000).
The next line contains initial state of the array: a0, a1, ..., an - 1 ( - 106 ≤ ai ≤ 106),ai are
integer. The third line contains integer m (0 ≤ m ≤ 200000), m —
the number of operartons. Next m lines contain one operation each. If line contains two integer lf, rg (0 ≤ lf, rg ≤ n - 1)
it means rmq operation, it contains three integers lf, rg, v (0 ≤ lf, rg ≤ n - 1; - 106 ≤ v ≤ 106)
— inc operation.
Output
For each rmq operation write result for it. Please, do not use %lld specificator
to read or write 64-bit integers in C++. It is preffered to use cout (also you may use %I64d).
Sample test(s)
input
4 1 2 3 4 4 3 0 3 0 -1 0 1 2 1
output
1 0 0
代码例如以下:
#include <cstdio> #include <algorithm> using namespace std; #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 //lson和rson分辨表示结点的左儿子和右儿子 //rt表示当前子树的根(root),也就是当前所在的结点 #define INF 0x3fffffff __int64 mmin[5000047]; __int64 col[5000047]; __int64 MIN(__int64 a, __int64 b) { if( a < b) return a; return b; } void pushup(int rt) { //sum[rt] = sum[rt<<1] + sum[rt<<1|1]; mmin[rt]=MIN(mmin[rt<<1], mmin[rt<<1|1]); } void pushdown(int rt, int m) { if(col[rt]) { col[rt<<1]+=col[rt]; col[rt<<1|1]+=col[rt]; mmin[rt<<1]+=col[rt]; mmin[rt<<1|1]+=col[rt]; col[rt]=0; } } void build(int l, int r, int rt) { col[rt]=0; if(l==r) { scanf("%I64d", &mmin[rt]); return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt); } void update(int L, int R, int v, int l, int r, int rt) { if(L<=l && r<=R) { col[rt]+=v; mmin[rt]+=v; return ; } pushdown(rt, r-l+1); int m=(l+r)>>1; if(L<=m) update(L, R, v, lson); if(R>m) update(L, R, v, rson); pushup(rt); } __int64 query(int L, int R, int l, int r, int rt) {//查询区间[L,R]中的最小值 if(L<=l && r<=R)//当前结点全然包括在查询区间内 return mmin[rt]; pushdown(rt, r-l+1); int m=(l+r)>>1; __int64 ret=INF; if(L<=m)//往左走 ret=MIN(ret, query(L, R, lson)); if(R>m)//往右走 ret=MIN(ret, query(L, R, rson)); return ret; } int main() { int n, m, a, b, c; char op; scanf("%d", &n); build(1, n, 1); scanf("%d", &m); while(m--) { scanf("%d%d%c", &a, &b, &op); a++;//将区间转换为是1到n b++; if(a<=b) { if(op==' ')//意味着是输入三个数的操作 { scanf("%d", &c); if(c==0) continue; update(a, b, c, 1, n, 1); } else printf("%I64d\n", query(a, b, 1, n, 1)); } else { if(op==' ') { scanf("%d", &c); if(c==0) continue; update(a, n, c, 1, n, 1);//拆分区间为a到n和1到b update(1, b, c, 1, n, 1); } else printf("%I64d\n", MIN(query(a, n, 1, n, 1), query(1, b, 1, n, 1))); } } return 0; }
相关文章推荐
- Diesel watches uk are presents for the trendy from a world-class designer
- Caffe代码导读(1):Protobuf例子
- 开发可变长参数的方法。
- Java_ArrayList与List解析
- android开发动画总结二(frame animation)
- Postfix邮件服务器搭建(四)
- cocos2dX 音乐和声音效果
- Cocos2dx-自定义怪物伤害值
- 侧边导航栏自动获取文章的高度
- react组件生命周期过程
- Caffe代码导读(0):路线图
- openwrt中luci学习笔记
- jQuery
- Android获取View 的坐标和屏幕高度、状态栏高度、标题栏高度
- Postfix邮件服务器搭建(三)
- mysql -- 预处理语句
- 【转】android自动化测试之MonkeyRunner使用实例(三)
- Android 4.4 Launcher3——导入eclipse进行调试
- 关于SSDB的网络模型
- java与 C++ 之间进行 SOCKET 通信