原题链接: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. C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=.答案是6个Firs ...

  2. 构造一个简单的linux系统

    1.搭建环境 cd ~/Work/ wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz xz -d linux- ...

  3. C# 操作XML 如果不存在创建 存在直接追加

    #region 写操作日志----------------这种格式 //<Log 操作人="Admin" 操作结果="成功" 结果详情="数据导 ...

  4. CSS3之阴影

    CSS3中新增属性-阴影,可以做出很多漂亮的效果. 文字阴影text-shadow text-shadow属性值的顺序: text-shadow: h-shadow v-shadow blur col ...

  5. 使用fiddler2抓取手机发出的请求信息

    fiddler2 简介:抓包软件,可以替换服务器js,从而实现本地调试 初始化设置: 1.工具——fiddler选项——常规——允许远程计算机连接(打钩)     2.按下图设置   3.设置连接,如 ...

  6. ansible检测链路状态和切换状态

    控制机 ansible.cfg callback_plugins = /usr/share/ansible/plugins/callback:/opt/ansible/plugins/callback ...

  7. css选择器分类

    css选择器大致可以分为10大类: 1.元素选择器 如:p{} 2.类选择器 如:.xx{} 3.ID选择器 如:#xx{} 4.关联选择器 如:p a{} 5.子元素选择器 如:p>a{} 6 ...

  8. 检查字符串长度 检查字符串是否为空 用正则表达式验证出版物的ISBN号 用正则表达式验证邮证编码 验证字符串中是否含有汉字

    <?php /** * 常用的正则表达式来验证信息.如:网址 邮箱 手机号等 */ class check { /** * 正则表达式验证email格式 * * @param string $s ...

  9. grub丢失的修复

    使用安装光盘进入rescure模式,经过配置后进入一个bashbash# grubgrub> root (hd0,6)grub> setup (hd0)重启即可

  10. JavaScript入门基础

    JavaScript基本语法 1.运算符 运算符就是完成操作的一系列符号,它有七类: 赋值运算符(=,+=,-=,*=,/=,%=,<<=,>>=,|=,&=).算术运 ...