原题链接: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. visio2007无法拖动

    连按两下键盘上的 “Esc” 键

  2. CODEVS 1036 商务旅行

    题目描述 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任 ...

  3. python常用内置函数

    Python所以内置函数如下: 下面列举一些常用的内置函数: chr()和ord() chr()将数字转换为对应的ascii码表字母 >>> r=chr(65) >>&g ...

  4. sql server安装程序无法验证服务账户是什么原因

    为了帮助网友解决“sql server安装程序无法验证服务”相关的问题,中国学网通过互联网对“sql server安装程序无法验证服务”相关的解决方案进行了整理,用户详细问题包括:能是尚未向所有要安装 ...

  5. A new start!

    从今天起,开始每天晚上拿出来半个小时到一个小时的时间来总结今天我做的那些事情,有哪些进步,有哪些不足,有哪些心得和笔记. 以前的学习都是每天学完就往脑袋后面一放,导致很多东西当时学会了,但是后面就都想 ...

  6. cacti yum快速部署

    简述:本来是编译安装的,由于编译过程中库文件关联太多,安装文件一定要有顺序性,报错太多,到了rrdtool这一步说什么都安装不过去了,由于时间问 题,选择了yum安装,对于编译安装,这个要简单多了,她 ...

  7. spring整合freemarker 自定义标签

    1.自定义标签实现 TemplateDirectiveModel 接口 2.spring 配置,注意标红的两行 <bean id="freemarkerConfig" cla ...

  8. C# 正则表达式及常用正则表达式

    元字符 描述 .点 匹配任何单个字符.例如正则表达式r.t匹配这些字符串:rat.rut.r t,但是不匹配root. $ 匹配行结束符.例如正则表达式weasel$ 能够匹配字符串"He' ...

  9. Spring框架搭建遇到的问题汇总

    1.The resource is not on the build path of a Java project 然后把相应的依赖加入构建路径 2.Type mismatch: cannot con ...

  10. Android IOS WebRTC 音视频开发总结(二七)-- whatsapp之转发优先

    最近看了一篇老外在webrtcHacks上写的文章,主要介绍webrtc和whatsapp的传输机制,蛮好的,加上自己的理解进行总结, 希望对大伙有所帮助,转载请说明出处,原文来自博客园RTC.Bla ...