原题链接:http://acdream.info/problem?pid=1738 
树套树裸题,如下:

 #include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#define lc root<<1
#define rc root<<1|1
using std::sort;
using std::lower_bound;
using std::upper_bound;
const int Max_N = ;
const int INF = ~0u >> ;
struct Node {
int v, s, c;
Node *ch[];
inline void set(int _v, int _s, Node *p) {
v = _v, s = c = _s;
ch[] = ch[] = p;
}
inline void push_up() {
s = ch[]->s + ch[]->s + c;
}
inline int cmp(int x) const {
return x == v ? - : x > v;
}
};
struct SizeBalanceTree {
int top, ans, tot, sum, arr[Max_N];
Node *null, *tail, stack[Max_N * ];
Node *store[Max_N << ], *ptr[Max_N << ];
inline void init(int n) {
top = ;
tail = &stack[];
null = tail++;
null->set(, , NULL);
for (int i = ; i <= n; i++) scanf("%d", &arr[i]);
seg_built(, , n);
}
inline Node *newNode(int v) {
Node *p = null;
if (!top) p = tail++;
else p = store[--top];
p->set(v, , null);
return p;
}
inline void rotate(Node *&x, int d) {
Node *k = x->ch[!d];
x->ch[!d] = k->ch[d];
k->ch[d] = x;
k->s = x->s;
x->push_up();
x = k;
}
inline void Maintain(Node *&x, int d) {
if (!x->ch[d]->s) return;
if (x->ch[d]->ch[d]->s > x->ch[!d]->s) {
rotate(x, !d);
} else if (x->ch[d]->ch[!d]->s > x->ch[!d]->s) {
rotate(x->ch[d], d), rotate(x, !d);
} else {
return;
}
Maintain(x, ), Maintain(x, );
}
inline void insert(Node *&x, int v) {
if (x == null) {
x = newNode(v);
return;
} else {
x->s++;
int d = x->cmp(v);
if (- == d) {
x->c++;
return;
}
insert(x->ch[d], v);
x->push_up();
Maintain(x, d);
}
}
inline void del(Node *&x, int v) {
if (!x->s) return;
x->s--;
int d = x->cmp(v);
if (- == d) {
if (x->c > ) {
x->c--;
return;
} else if (!x->ch[]->s || !x->ch[]->s) {
store[top++] = x;
x = x->ch[]->s ? x->ch[] : x->ch[];
} else {
Node *ret = x->ch[];
for (; ret->ch[]->s; ret = ret->ch[]);
del(x->ch[], x->v = ret->v);
}
} else {
del(x->ch[d], v);
}
if (x->s) x->push_up();
}
inline Node *get_min(Node *x) {
for (; x->ch[]->s; x = x->ch[]);
return x;
}
inline int find(Node *x, int v) {
while (x->s && x->v != v) x = x->ch[v > x->v];
return x->c;
}
inline int count(Node *x, int v) {
int res = , t = ;
for (; x->s;) {
t = x->ch[]->s;
if (v < x->v) x = x->ch[];
else res += t + x->c, x = x->ch[];
}
return res;
}
inline void seg_built(int root, int l, int r) {
ptr[root] = null;
for (int i = l; i <= r; i++) insert(ptr[root], arr[i]);
if (l == r) return;
int mid = (l + r) >> ;
seg_built(lc, l, mid);
seg_built(rc, mid + , r);
}
inline void seg_modify(int root, int l, int r, int pos, int v){
if (pos > r || pos < l) return;
del(ptr[root], arr[pos]);
insert(ptr[root], v);
if (l == r) return;
int mid = (l + r) >> ;
seg_modify(lc, l, mid, pos, v);
seg_modify(rc, mid + , r, pos, v);
}
inline void seg_query_min(int root, int l, int r, int x, int y) {
if (x > r || y < l) return;
if (x <= l && y >= r) {
Node *ret = get_min(ptr[root]);
if (ret->v < ans) ans = ret->v;
return;
}
int mid = (l + r) >> ;
seg_query_min(lc, l, mid, x, y);
seg_query_min(rc, mid + , r, x, y);
}
inline void seg_query_tot(int root, int l, int r, int x, int y, int val) {
if (x > r || y < l) return;
if (x <= l && y >= r) {
tot += find(ptr[root], val);
return;
}
int mid = (l + r) >> ;
seg_query_tot(lc, l, mid, x, y, val);
seg_query_tot(rc, mid + , r, x, y, val);
}
inline void seg_query_count(int root, int l, int r, int x, int y, int val) {
if (x > r || y < l) return;
if (x <= l && y >= r) {
sum += count(ptr[root], val);
return;
}
int mid = (l + r) >> ;
seg_query_count(lc, l, mid, x, y, val);
seg_query_count(rc, mid + , r, x, y, val);
}
inline void gogo(int n) {
int a, b, c, d;
scanf("%d", &a);
if ( == a) {
scanf("%d %d", &b, &c);
seg_modify(, , n, b, c), arr[b] = c;
} else if ( == a) {
ans = INF, tot = ;
scanf("%d %d", &b, &c);
seg_query_min(, , n, b, c);
seg_query_tot(, , n, b, c, ans);
printf("%d %d\n", ans, tot);
} else {
sum = ;
scanf("%d %d %d", &b, &c, &d);
seg_query_count(, , n, b, c, d);
printf("%d\n", sum);
}
}
}sbt;
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w+", stdout);
#endif;
int n, m;
while (~scanf("%d %d", &n, &m)) {
sbt.init(n);
while (m--) sbt.gogo(n);
}
return ;
}

如果觉得sb树跑的慢,再写个红黑树吧。。。

 #include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#define lc root<<1
#define rc root<<1|1
const int Max_N = ;
const int INF = ~0u >> ;
struct Node {
int data, s, c;
bool color;
Node *fa, *ch[];
inline void set(int _v, bool _color, int i, Node *p) {
data = _v, color = _color, s = c = i;
fa = ch[] = ch[] = p;
}
inline void push_up() {
s = ch[]->s + ch[]->s + c;
}
inline void push_down() {
for (Node *x = this; x->s; x = x->fa) x->s--;
}
inline int cmp(int v) const {
return data == v ? - : v > data;
}
};
struct RedBlackTree {
int top, ans, tot, sum, arr[Max_N];
Node *null, *tail;
Node stack[Max_N * ], *store[Max_N << ], *ptr[Max_N << ];
inline void init(int n) {
top = ;
tail = &stack[];
null = tail++;
null->set(, , , NULL);
for (int i = ; i <= n; i++) scanf("%d", &arr[i]);
seg_built(, , n);
}
inline Node *newNode(int v) {
Node *p = null;
if (!top) p = tail++;
else p = store[--top];
p->set(v, , , null);
return p;
}
inline void rotate(int root, Node* &x, bool d) {
Node *y = x->ch[!d];
x->ch[!d] = y->ch[d];
if (y->ch[d]->s) y->ch[d]->fa = x;
y->fa = x->fa;
if (!x->fa->s) ptr[root] = y;
else x->fa->ch[x->fa->ch[] != x] = y;
y->ch[d] = x;
x->fa = y;
y->s = x->s;
x->push_up();
}
inline void insert(int root, int v) {
Node *x = ptr[root], *y = null;
while (x->s) {
x->s++, y = x;
int d = x->cmp(v);
if (- == d) {
x->c++;
return;
}
x = x->ch[d];
}
x = newNode(v);
if (y->s) y->ch[v > y->data] = x;
else ptr[root] = x;
x->fa = y;
insert_fix(root, x);
}
inline void insert_fix(int root, Node* &x) {
while (x->fa->color) {
Node *par = x->fa, *Gp = par->fa;
bool d = par == Gp->ch[];
Node *uncle = Gp->ch[d];
if (uncle->color) {
par->color = uncle->color = ;
Gp->color = ;
x = Gp;
} else if (x == par->ch[d]) {
rotate(root, x = par, !d);
} else {
Gp->color = ;
par->color = ;
rotate(root, Gp, d);
}
}
ptr[root]->color = ;
}
inline Node *find(Node *x, int data) {
while (x->s && x->data != data) x = x->ch[x->data < data];
return x;
}
inline void del_fix(int root, Node* &x) {
while (x != ptr[root] && !x->color) {
bool d = x == x->fa->ch[];
Node *par = x->fa, *sibling = par->ch[d];
if (sibling->color) {
sibling->color = ;
par->color = ;
rotate(root, x->fa, !d);
sibling = par->ch[d];
} else if (!sibling->ch[]->color && !sibling->ch[]->color) {
sibling->color = , x = par;
} else {
if (!sibling->ch[d]->color) {
sibling->ch[!d]->color = ;
sibling->color = ;
rotate(root, sibling, d);
sibling = par->ch[d];
}
sibling->color = par->color;
sibling->ch[d]->color = par->color = ;
rotate(root, par, !d);
break;
}
}
x->color = ;
}
inline void del(int root, int data) {
Node *z = find(ptr[root], data);
if (!z->s) return;
if (z->c > ) {
z->c--;
z->push_down();
return;
}
Node *y = z, *x = null;
if (z->ch[]->s && z->ch[]->s) {
y = z->ch[];
while (y->ch[]->s) y = y->ch[];
}
x = y->ch[!y->ch[]->s];
x->fa = y->fa;
if (!y->fa->s) ptr[root] = x;
else y->fa->ch[y->fa->ch[] == y] = x;
if (z != y) z->data = y->data, z->c = y->c;
y->fa->push_down();
for (Node *k = y->fa; y->c > && k->s && k != z; k = k->fa) k->s -= y->c - ;
if (!y->color) del_fix(root, x);
store[top++] = y;
}
inline Node* get_min(Node *x) {
for (; x->ch[]->s; x = x->ch[]);
return x;
}
inline int count(Node *x, int v) {
int res = , t = ;
for (; x->s;) {
t = x->ch[]->s;
if (v < x->data) x = x->ch[];
else res += t + x->c, x = x->ch[];
}
return res;
}
inline void seg_built(int root, int l, int r) {
ptr[root] = null;
for (int i = l; i <= r; i++) insert(root, arr[i]);
if (l == r) return;
int mid = (l + r) >> ;
seg_built(lc, l, mid);
seg_built(rc, mid + , r);
}
inline void seg_modify(int root, int l, int r, int pos, int v){
if (pos > r || pos < l) return;
del(root, arr[pos]);
insert(root, v);
if (l == r) return;
int mid = (l + r) >> ;
seg_modify(lc, l, mid, pos, v);
seg_modify(rc, mid + , r, pos, v);
}
inline void seg_query_min(int root, int l, int r, int x, int y) {
if (x > r || y < l) return;
if (x <= l && y >= r) {
Node *ret = get_min(ptr[root]);
if (ret->data < ans) ans = ret->data;
return;
}
int mid = (l + r) >> ;
seg_query_min(lc, l, mid, x, y);
seg_query_min(rc, mid + , r, x, y);
}
inline void seg_query_tot(int root, int l, int r, int x, int y, int val) {
if (x > r || y < l) return;
if (x <= l && y >= r) {
tot += find(ptr[root], val)->c;
return;
}
int mid = (l + r) >> ;
seg_query_tot(lc, l, mid, x, y, val);
seg_query_tot(rc, mid + , r, x, y, val);
}
inline void seg_query_count(int root, int l, int r, int x, int y, int val) {
if (x > r || y < l) return;
if (x <= l && y >= r) {
sum += count(ptr[root], val);
return;
}
int mid = (l + r) >> ;
seg_query_count(lc, l, mid, x, y, val);
seg_query_count(rc, mid + , r, x, y, val);
}
inline void gogo(int n) {
int a, b, c, d;
scanf("%d", &a);
if ( == a) {
scanf("%d %d", &b, &c);
seg_modify(, , n, b, c), arr[b] = c;
} else if ( == a) {
ans = INF, tot = ;
scanf("%d %d", &b, &c);
seg_query_min(, , n, b, c);
seg_query_tot(, , n, b, c, ans);
printf("%d %d\n", ans, tot);
} else {
sum = ;
scanf("%d %d %d", &b, &c, &d);
seg_query_count(, , n, b, c, d);
printf("%d\n", sum);
}
}
}rbt;
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w+", stdout);
#endif
int n, m;
while (~scanf("%d %d", &n, &m)) {
rbt.init(n);
while (m--) rbt.gogo(n);
}
return ;
}

acdream 1738 世风日下的哗啦啦族I的更多相关文章

  1. acdream 1738 世风日下的哗啦啦族I 分块

    世风日下的哗啦啦族I Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acdream.info/problem?pid=1738 Descri ...

  2. Acdream 1738 世风日下的哗啦啦族I 树套树

    世风日下的哗啦啦族I Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acdream.info/problem?pid=1738 Descri ...

  3. ACdream 1738 世风日下的哗啦啦族I(分块大法+二分)

    世风日下的哗啦啦族I Time Limit: 4000/2000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit S ...

  4. 世风日下的哗啦啦族I (简单分块模板)

    题目链接 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define inf 0x7ffffff ...

  5. 2017"百度之星"程序设计大赛 - 资格赛【1001 Floyd求最小环 1002 歪解(并查集),1003 完全背包 1004 01背包 1005 打表找规律+卡特兰数】

    度度熊保护村庄 Accepts: 13 Submissions: 488 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3276 ...

  6. HDU 6081 度度熊的王国战略(全局最小割堆优化)

    Problem Description度度熊国王率领着喵哈哈族的勇士,准备进攻哗啦啦族.哗啦啦族是一个强悍的民族,里面有充满智慧的谋士,拥有无穷力量的战士.所以这一场战争,将会十分艰难.为了更好的进攻 ...

  7. HDU 6081 度度熊的王国战略(全局最小割Stoer-Wagner算法)

    Problem Description 度度熊国王率领着喵哈哈族的勇士,准备进攻哗啦啦族. 哗啦啦族是一个强悍的民族,里面有充满智慧的谋士,拥有无穷力量的战士. 所以这一场战争,将会十分艰难. 为了更 ...

  8. HDU 6081 度度熊的王国战略【并查集/数据弱水题/正解最小割算法】

    链接6081 度度熊的王国战略 Time Limit: 40000/20000 MS (Java/Others) Memory Limit: 32768/132768 K (Java/Others) ...

  9. [SinGuLaRiTy] 2017 百度之星程序设计大赛-资格赛

    [SinGuLaRiTy-1034] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 度度熊保护村庄  Time Limit: 2000/10 ...

随机推荐

  1. BZOJ1996 合唱队 区间DP

    OJ地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1996 设dp(i,j,k)代表在理想结果中[i,j]段最后添加的是i或j(k=0or1) ...

  2. 学习总结 for循环语句的应用

    for(初始值:条件表达式:状态改变) { } \n 表示换行   \ttab键   \\写出一个斜杠 例题解释 // 输出一个数,打印一到n出来 int n = int.Parse(Console. ...

  3. express 框架初步体验

    一. 安装express 1.打开cmd  全局安装express 输入:npm install -gd express 2. 安装命令行工具,不然你输入express 会出现 不是内部命令. 输入: ...

  4. b2c项目基础架构分析(一)b2c 大型站点方案简述 已补充名词解释

    我最近一直在找适合将来用于公司大型bs,b2b b2c的基础架构. 实际情况是要建立一个bs架构b2b.b2c的网站,当然还包括wap站点.手机app站点. 一.现有公司技术人员现状: 1.熟悉asp ...

  5. 在CentOS 7上安装Python3.5源码包

    最近开始系统学习Python 3.5,发现CentOS 7系统自带的python版本是Python 2.7.现在要使用Python 3.5该怎么办?方法大体跟安装其他程序一样.以下为详细经过: 1.事 ...

  6. js动态生成JSON树

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. meta 标签属性(网站兼容与优化需要)

    概要 标签提供关于HTML文档的元数据.元数据不会显示在页面上,但是对于机器是可读的.它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务. —— W3School ...

  8. 百度地图API示例之添加自定义控件

    代码 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" cont ...

  9. c#中执行多条sql语句【ORA-00911: 无效字符】

    问题描述: 在plsql里执行多条sql语句的时候,使用“,”(逗号)分隔,测试可以执行多条,而在C#执行多条sql语句的时候[ORA-00911: 无效字符]. 有时我们需要一次性执行多条sql语句 ...

  10. mac下,利用homebrew安装PHP+Mysql+Nginx

    具体可以参考直通车 http://blog.frd.mn/install-nginx-php-fpm-mysql-and-phpmyadmin-on-os-x-mavericks-using-home ...