bzoj 3110
来源:互联网 发布:ubuntu 16.04 安装完 编辑:程序博客网 时间:2024/05/22 07:59
线段树套线段树,挺不错的一道数据结构题。
先读入所有询问并离散化,然后在外层建 权值线段树 ,
权值线段树的每个结点建一棵 维护区间和 的线段树。
直接建树空间
时间复杂度
空间复杂度
学到了新姿势,重载括号运算符:
int& operator [](int id) { return *(__arr + id); }
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <vector>#include <utility>#include <stack>#include <queue>#include <iostream>#include <algorithm>template<class Num>void read(Num &x){ char c; int flag = 1; while((c = getchar()) < '0' || c > '9') if(c == '-') flag *= -1; x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = (x<<3) + (x<<1) + (c-'0'); x *= flag; return;}template<class Num>void write(Num x){ if(x < 0) putchar('-'), x = -x; static char s[20];int sl = 0; while(x) s[sl++] = x%10 + '0',x /= 10; if(!sl) {putchar('0');return;} while(sl) putchar(s[--sl]);}struct vetor{#define begin() (__arr + 1)#define end() (__arr + __len + 1) int *__arr, __len; void set(int size) { __len = 0, __arr = (int*)malloc(sizeof(int)*size); } void push_back(int x) { __arr[++__len] = x; } int size() { return __len; } void unique() { std::sort(begin(),end()); __len = std::unique(begin(),end()) - begin(); } int find(int x) { return std::lower_bound(begin(), end(), x)-begin()+1; } void erase() { __len = 0; } int& operator [](int id) { return *(__arr + id); }#undef begin#undef end}bowl;#define REP(__i,__start,__end) for(int __i = (__start); __i <= (__end); __i++)const int maxm = 5e4 + 50, maxn = 5e4 + 50;const int logM = 16, logN = logM, size = logM*(logN<<1)*maxm + (maxm << 2);struct type_op{ int tp, a, b, c; void init() { read(tp), read(a), read(b), read(c); if(tp == 1) bowl.push_back(c); }}op[maxm];int val[maxm << 2], lc[size], rc[size], cnt[size], addv[size];int n, m, ind;int pushdown(int si,int ll,int rr){ int mid = ll + rr >> 1; if(!lc[si]) lc[si] = ++ind; if(!rc[si]) rc[si] = ++ind; cnt[lc[si]] += addv[si]*(mid - ll + 1); cnt[rc[si]] += addv[si]*(rr - mid); addv[lc[si]] += addv[si], addv[rc[si]] += addv[si], addv[si] = 0; return mid;}void update(int si){ cnt[si] = cnt[lc[si]] + cnt[rc[si]];}void insert(int l,int r,int ll,int rr,int si){ if(l == ll && r == rr) cnt[si] += r - l + 1, addv[si] ++; else { int mid = pushdown(si, ll, rr); if(mid < l) insert(l, r, mid + 1, rr, rc[si]); else if(r <= mid) insert(l, r, ll, mid, lc[si]); else { insert(l, mid, ll, mid, lc[si]); insert(mid + 1, r, mid + 1, rr, rc[si]); } update(si); }}int query(int l,int r,int ll,int rr,int si){ if(l == ll && r == rr) return cnt[si]; else { int mid = pushdown(si, ll, rr); if(mid < l) return query(l, r, mid + 1, rr, rc[si]); else if(r <= mid) return query(l, r, ll, mid, lc[si]); else return query(l, mid, ll, mid, lc[si]) + query(mid + 1, r, mid + 1, rr, rc[si]); update(si); }}#define L(x) ((x)<<1)#define R(x) ((x)<<1|1)void build(int ll,int rr,int sv){ val[sv] = ++ind; if(ll != rr) { int mid = ll + rr >> 1; build(ll, mid, L(sv)); build(mid + 1, rr, R(sv)); }}void add(int l,int r,int v,int ll,int rr,int si){ insert(l, r, 1, n, val[si]); if(ll != rr) { int mid = ll + rr >> 1; if(v <= mid) add(l, r, v, ll, mid, L(si)); else add(l, r, v, mid + 1, rr, R(si)); } }int ask(int l,int r,int v,int ll,int rr,int si){ if(ll == rr) return ll; int mid = ll + rr >> 1, rcnt; if((rcnt = query(l, r, 1, n, val[R(si)])) >= v) return ask(l, r, v, mid + 1, rr, R(si)); else return ask(l, r, v - rcnt, ll, mid, L(si)); }#undef L#undef Rvoid init(){ bowl.set(maxm), read(n), read(m); REP(i, 1, m) op[i].init();}void prework(){ bowl.unique(); REP(i, 1, m) if(op[i].tp == 1) op[i].c = bowl.find(op[i].c); build(1, bowl.size(), 1);}void solve(){ for(int i = 1; i <= m; i++) { if(op[i].tp == 1) add(op[i].a, op[i].b, op[i].c, 1, bowl.size(), 1); else write(bowl[ask(op[i].a, op[i].b, op[i].c, 1, bowl.size(), 1)]), puts(""); }}int main(){#ifndef ONLINE_JUDGE freopen("3110.in","r",stdin); freopen("3110.out","w",stdout);#endif init(); prework(); solve();#ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout);#endif return 0;}
0 0
- bzoj 3110
- BZOJ 3110 题解
- [BZOJ ]
- BZOJ****-****
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- bzoj
- bzoj
- BZOJ
- BZOJ
- HDU 2032
- RMAN正确地删除Archivelog以及设置有备库的归档删除策略
- HDU 4086
- Head First Java 中文高清版
- 数据结构:快状链表(数组链表联合)
- bzoj 3110
- 使用逆波兰式(后缀表达式)实现多功能计算器
- 查找输入整数二进制中1的个数
- Target runtime Apache Tomcat 6.0 is not defined 解决方法
- linux启动后自动执行某个脚本
- 单例设计模式的两种方式
- GPIO Sysfs Interface for Userspace
- Controlling GPIO from Linux User Space
- HDU 2037 今年暑假不AC