SPOJ 3261 (树套树傻逼题)
As another one of their crazy antics, the N (1 ≤ N ≤ 100,000) cows want Farmer John to race against the clock to answer some of their pressing questions.
The cows are lined up in a row from 1 to N, and each one is holding a sign representing a number, Ai (1 ≤ Ai≤ 1,000,000,000). The cows need FJ to perform Q (1 ≤ Q ≤ 50,000) operations, which can be either of the following:
- Modify cow i's number to X (1 ≤ X ≤ 1,000,000,000). This will be represented in the input as a line containing the letter M followed by the space-separated numbers i and X.
- Count how many cows in the range [P, Q] (1 ≤ P ≤ Q ≤ N) have Ai ≤ X (0 ≤ X ≤ 1,000,000,000). This will be represented in the input as a line containing the letter C followed by the space-separated numbers P, Q, and X.
Of course, FJ would like your help.
Input
The first line gives the integers N and Q, and the next N lines give the initial values of Ai. Finally, the next Q lines each contain a query of the form "M i X" or "C P Q X".
Output
Print the answer to each 'C' query, one per line.
Example
Input: 4 6 3 4 1 7 C 2 4 4 M 4 1 C 2 4 4 C 1 4 5 M 2 10 C 1 3 9 Output: 2 3 4 2
题意:给出一段序列,要求有两种操作, 1 修改一个位置的数字, 2 查询一段区间内的小于val的数字有多少个。
sl: 这是区间查询,所以用线段树维护就好了,但是查询小于val的数字有多少个,所以直接随便用一个平衡树求一个rank就好了。 最近刚刚学了SBT.
试了试模板,还是要手敲为妙。 加了挂还是超时,不知道为何。 应该有好方法。 用treap貌似能过?
1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <algorithm>
5 #include <cmath>
6
7 using namespace std;
8
9 const int maxn = ;
10
11 struct Node {
12 int key, val;
13 Node(){};
14 Node(int a, int b) { key = a; val = b; }
15 bool operator < (Node b) { return val < b.val; }
16 bool operator <= (Node b) { return val <= b.val; }
17 bool operator > (Node b) { return val > b.val; }
18 bool operator >= (Node b) { return val >= b.val; }
19 bool operator == (Node b) { return val == b.val; }
20 Node operator + (int a) {
21 return Node(key, val+a) > Node(key, val) ? Node(key, val+a) : Node(key, val-a);
22 }
23 };
24
25 int sz[maxn*];
26 int key[maxn*];
27 int lch[maxn*];
28 int rch[maxn*];
29 int tot;
30
31 template<typename Type>
32 class SBT
33 {
34 public:
35 SBT() { Clear(); }
36 void Clear() { root = ; lch[] = rch[] = sz[] = ; }
37 static void ClearAll() { tot = ; }
38 int Size() { return sz[root]; }
39 bool Empty() { return == sz[root]; }
40 bool Find(Type k) { return Find(root, k); }
41 void InsertR(Type k) { Insert(root, k); } // 可重复插入
42 void Insert(Type k) { if (!Find(k)) Insert(root, k); }
43 void Delete(Type k) { if (Find(k)) Delete(root, k); }
44 void DeleteSmaller(Type k) { DeleteSmaller(root, k); }
45 int GetRank(Type k) { return GetRank(root, k); }
46 Type GetKth(int k) { return GetKth(root, k); }
47 Type GetMin() { return GetKth(root, ); }
48 Type GetMax() { return GetKth(root, Size()); }
49 Type GetPre(Type k) { return GetPre(root, k); }
50 Type GetSuc(Type k) { return GetSuc(root, k); }
51 int GetSmaller(Type k) { return GetSmaller(root, k); } // 返回小于k的元素的个数
52
53 private:
54 void LeftRotate(int &t) {
55 int k = rch[t];
56 rch[t] = lch[k];
57 lch[k] = t;
58 sz[k] = sz[t];
59 sz[t] = + sz[lch[t]] + sz[rch[t]];
60 t = k;
61 }
62 void RightRotate(int &t) {
63 int k = lch[t];
64 lch[t] = rch[k];
65 rch[k] = t;
66 sz[k] = sz[t];
67 sz[t] = + sz[lch[t]] + sz[rch[t]];
68 t = k;
69 }
70 void Maintain(int &t, bool flag) {
71 if ( == t) return ;
72 if (false == flag) {
73 if (sz[lch[lch[t]]] > sz[rch[t]]) {
74 RightRotate(t);
75 } else if (sz[rch[lch[t]]] > sz[rch[t]]) {
76 LeftRotate(lch[t]);
77 RightRotate(t);
78 } else {
79 return ;
80 }
81 } else {
82 if (sz[rch[rch[t]]] > sz[lch[t]]) {
83 LeftRotate(t);
84 } else if (sz[lch[rch[t]]] > sz[lch[t]]) {
85 RightRotate(rch[t]);
86 LeftRotate(t);
87 } else {
88 return ;
89 }
90 }
91 Maintain(lch[t], false);
92 Maintain(rch[t], true);
93 Maintain(t, false);
94 Maintain(t, true);
95 }
96 Type GetPre(int t, Type k) {
97 if ( == k) return k;
98 if (k <= key[t]) return GetPre(lch[t], k);
99 Type tmp = GetPre(rch[t], k);
if (tmp == k) return key[t];
return tmp;
}
Type GetSuc(int t, Type k) {
if ( == root) return k;
if (k >= key[t]) return GetSuc(rch[t], k);
Type tmp = GetSuc(lch[t], k);
if (tmp == k) return key[t];
return tmp;
}
Type GetKth(int t, int k) {
if (sz[lch[t]] >= k) return GetKth(lch[t], k);
if (sz[lch[t]] == k - ) return key[t];
return GetKth(rch[t], k - sz[lch[t]] - );
}
int GetRank(int t, Type k) {
if ( == t) return ;
if (k < key[t]) return GetRank(lch[t], k);
return sz[lch[t]] + + GetRank(rch[t], k);
}
int GetSmaller(int t, Type k) {
if ( == t) return ;
if (k <= key[t]) return GetSmaller(lch[t], k);
return sz[lch[t]] + + GetSmaller(rch[t], k);
}
bool Find(int t, Type k) {
if ( == t) return false;
else if (k < key[t]) return Find(lch[t], k);
else return (key[t] == k || Find(rch[t], k));
}
void Insert(int &t, Type k) {
if ( == t) {
t = ++tot;
lch[t] = rch[t] = ;
sz[t]= ;
key[t] = k;
return ;
}
sz[t]++;
if (k < key[t]) Insert(lch[t], k);
else Insert(rch[t], k);
Maintain(t, k >= key[t]);
}
void DeleteSmaller(int &t , Type k) {
if ( == t) return ;
if ( key[t] < k ) {
t = rch[t];
DeleteSmaller(t , key);
} else {
DeleteSmaller(lch[t] , k);
sz[t] = + sz[lch[t]] + sz[rch[t]];
}
}
Type Delete(int &t, Type k) {
sz[t]--;
if ((key[t] == k) || (k < key[t] && == lch[t]) || (k > key[t] && == rch[t])) {
Type tmp = key[t];
if ( == lch[t] || == rch[t]) {
t = lch[t] + rch[t];
} else {
key[t] = Delete(lch[t], key[t] + );
}
return tmp;
} else {
if (k < key[t]) {
return Delete(lch[t], k);
} else {
return Delete(rch[t], k);
}
}
}
private:
int root;
};
SBT <int> sbt[maxn<<];
int a[maxn];
void build(int L,int R,int o) {
sbt[o].Clear();
for(int i=L;i<=R;i++) {
sbt[o].InsertR(a[i]);
}
if(L==R) return ;
int mid=(L+R)>>;
build(L,mid,o<<);
build(mid+,R,o<<|);
}
void Update(int L,int R,int o,int pos,int val) {
sbt[o].Delete(a[pos]);
sbt[o].InsertR(val);
if(L==R) return ;
int mid=(L+R)>>;
if(pos<=mid) Update(L,mid,o<<,pos,val);
if(pos>mid) Update(mid+,R,o<<|,pos,val);
}
int Query(int L,int R,int o,int ls,int rs,int val) {
if(ls<=L&&rs>=R) {
return sbt[o].GetRank(val);
}
int mid=(L+R)>>; int res=;
if(ls<=mid) res+=Query(L,mid,o<<,ls,rs,val);
if(rs>mid) res+=Query(mid+,R,o<<|,ls,rs,val);
return res;
}
inline int read()
{
int m=;
char ch=getchar();
while(ch<''||ch>''){ch=getchar(); }
while(ch>=''&&ch<=''){m=m*+ch-''; ch=getchar(); }
return m;
}
int main() {
int n,m; char op[];
int ls,rs,val;
while(scanf("%d %d",&n,&m)==) {
for(int i=;i<=n;i++) {
a[i]=read();
}
SBT<int> :: ClearAll();
build(,n,);
for(int i=;i<=m;i++) {
scanf("%s",op);
if(op[]=='C') {
ls=read(); rs=read(); val=read();
int ans=Query(,n,,ls,rs,val);
printf("%d\n",ans);
}
else {
ls=read(); rs=read();
Update(,n,,ls,val);
a[ls]=val;
}
}
}
return ;
238 }
SPOJ 3261 (树套树傻逼题)的更多相关文章
- BZOJ4644: 经典傻逼题【线段树分治】【线性基】
Description 这是一道经典傻逼题,对经典题很熟悉的人也不要激动,希望大家不要傻逼. 考虑一张N个点的带权无向图,点的编号为1到N. 对于图中的任意一个点集 (可以为空或者全集),所有恰好有一 ...
- BZOJ_3196_二逼平衡树_(树套树,线段树+Treap)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3196 可以处理区间问题的平衡树. 3196: Tyvj 1730 二逼平衡树 Time Lim ...
- bzoj3196: Tyvj 1730 二逼平衡树 树套树
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3196 题目: 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec ...
- ZJOI2013 K大数查询 和 LG3380【模板】二逼平衡树(树套树)
K大数查询 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c:如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的 ...
- P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)
P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...
- 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)
[模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...
- 洛谷P3380 【模板】二逼平衡树(树套树)(线段树+树状数组)
P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- 洛谷 P3380 【模板】二逼平衡树(树套树)-线段树套splay
P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...
- 「luogu3380」【模板】二逼平衡树(树套树)
「luogu3380」[模板]二逼平衡树(树套树) 传送门 我写的树套树--线段树套平衡树. 线段树上的每一个节点都是一棵 \(\text{FHQ Treap}\) ,然后我们就可以根据平衡树的基本操 ...
随机推荐
- Navicat无法连接Oracle数据库问题处理一例
需要通过Navicat连接Oracle数据库进行数据迁移,发现无法连接,报如下错误信息: 按照百度中的说明配置了正确的oci. 此时又报如下错误: 问题解决: 经测试发现与软件的版本有关系,本机的Or ...
- 转】MYSQL性能调优与架构设计之select count(*)的思考
原博文出自于: http://blog.fens.me/category/%E6%95%B0%E6%8D%AE%E5%BA%93/page/5/ 感谢! Posted: Feb 7, 2013 Tag ...
- Oracle 表-初步涉水不深(第一天)
oracle 关系型数据库 注释:面对大型数据处理,市场占有率40%多(但是目前正往分布式转换) 故事:本来一台大型计算机才能处理的数据,美国科学家用100台家用电脑连接,成功处理了数据.. tabl ...
- volley的框架安装与使用
最后一步非常重要 不然会报错: publish = project.has("release") 替换为: publish = project.hasProperty(&q ...
- 老潘 - ListView分析 - 学以致用篇(一)
ListView分析学以致用篇(1) 在我们查看别人的博客的时候,一个人是一个风格的.先说下我的风格,我喜欢思想类比,然后介绍知识,不太喜欢填鸭式的灌输.如果只是想单纯的从我的博客中直接看到代码,我个 ...
- 使用 ArrayAdapter 来定制 ListView
一个 ListView,其宽高都设为 match_parent,可以更省资源. activity_main.xml <ListView android:id="@+id/list_Vi ...
- 读取Java文件到byte数组的三种方式
package zs; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io ...
- vba,设置,excel,wps ,页面设置例子
Sub yemian()'按钮1点击触发 执行下面的命令With Sheets(1).PageSetup'对像是表格1的页面设置的函数PageSetup,下面是函数的属性修改前面加. .Orienta ...
- PHP面向对象考察点
面向对象三大特性 封装 封装性就是把对象的属性和服务结合成一个独立的相同单位,并尽可能隐蔽对象的内部细节,包含两个含义: 把对象的全部属性和全部服务结合在一起,形成一个不可分割的独立单位(即对象). ...
- GIT 获取指定历史版本代码
cd 到该项目的一个本地仓库下 log 查看提交记录,找到想要的提交记录,粘贴对应的希哈值 执行 git checkout 希哈值 这本地的这个仓库的代码就会变成你想要的那个版本的代码