线段树练习1
2017-11-06 10:16
190 查看
题意
n个数,m次操作,每次询问区间第k大,或者给区间加上一个数。
$数据范围:1 ≤ n,m ≤ 10^5 ,1 ≤ k ≤ 10。$
题解
由于k很小,直接在线段树内维护,前k大的数。
code
#include<cstdio> #include<cstring> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define N 100010 #define K 10 int n,m; struct Tree { int data[K]; Tree() {memset(data,0,sizeof(data));} Tree operator + (const Tree &a) const { Tree ret; int p1 = 0,p2 = 0; for (int i=0; i<K; ++i) if (data[p1] > a.data[p2]) ret.data[i] = data[p1++]; else ret.data[i] = a.data[p2++]; return ret; } }t[N<<2]; int a ,tag[N<<2]; inline int read() { int x = 0,f = 1;char ch = getchar(); for (; ch<'0'||ch>'9'; ch = getchar()) if (ch=='-') f = -1; for (; ch>='0'&&ch<='9'; ch = getchar()) x = x*10+ch-'0'; return x*f; } inline void pushup(int rt) { t[rt] = t[rt<<1] + t[rt<<1|1]; } inline void pushdown(int rt) { if (tag[rt]) { tag[rt<<1] += tag[rt]; for (int i=0; i<K; ++i) if (t[rt<<1].data[i]) t[rt<<1].data[i] += tag[rt];//只加有的数字 tag[rt<<1|1] += tag[rt]; for (int i=0; i<K; ++i) if (t[rt<<1|1].data[i]) t[rt<<1|1].data[i] += tag[rt]; tag[rt] = 0; } } void build(int l,int r,int rt) { if (l==r) { t[rt].data[0] = a[l]; return ; } int m = (l+r) >> 1; build (lson); build (rson); pushup(rt); } void update(int l,int r,int rt,int L,int R,int c) { if (L <= l && r <= R) { tag[rt] += c; for (int i=0; i<K; ++i) if (t[rt].data[i]) t[rt].data[i] += c; return ; } pushdown(rt); int m = (l+r) >> 1; if (L <= m) update(lson,L,R,c); if (R > m) update(rson,L,R,c); pushup(rt); } Tree query(int l,int r,int rt,int L,int R) { if (L <= l && r <= R) { return t[rt]; } pushdown(rt); Tree ret; int m = (l+r) >> 1; if (L <= m) ret = ret + query(lson,L,R); if (R > m) ret = ret + query(rson,L,R); return ret ; } int main() { int n = read(),m = read(); for (int i=1; i<=n; ++i) a[i] = read(); build(1,n,1); Tree ans; while (m--) { int opt = read(),l = read(),r = read(),k = read(); if (opt==0) { if (r-l+1 < k) puts("-1"); else { ans = query(1,n,1,l,r); printf("%d\n",ans.data[k-1]); } } else update(1,n,1,l,r,k); } return 0; }
by zhx p106 无题
相关文章推荐
- [Codevs] 1082 线段树练习3
- <线段树系列1> codevs 1080 线段树练习
- 线段树练习_codevs1080_线段树
- 1080 线段树练习 单点修改及区间查询
- Codevs1080 线段树练习
- 【codevs 1080~1082】线段树练习重做
- 2016夏季练习——线段树
- 线段树练习3
- 线段树练习
- 线段树练习4
- codevs 1080_线段树练习_树状数组
- <线段树系列2> codevs 1082 线段树练习2
- codevs4919 线段树练习4
- 1081 线段树练习 2 单点查询及区间修改
- CodeVS 1080 线段树练习 分块 块状数组
- 【codevs 1080】线段树练习
- 2016夏季练习——线段树
- 【codevs1082】线段树练习3——树状数组(改段求段)
- 线段树练习(1)
- 线段树练习POJ 3264