标签:
建颗权值线段树就行了...连离散化都不用...
没加读入优化就TLE, 加了就A掉了...而且还快了接近1/4....
------------------------------------------------------------------------------------------
#include<bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < n; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define M(l, r) (((l) + (r)) >> 1)
using namespace std;
const int maxn = 1000009;
struct Node {
Node *l, *r;
bool s;
Node() {
s = false;
}
inline void update() {
s = l->s || r->s;
}
} pool[maxn << 1], *pt = pool, *root;
void build(Node* t, int l, int r) {
if(r > l) {
int m = M(l, r);
build(t->l = pt++, l, m);
build(t->r = pt++, m + 1, r);
}
}
int n, v, type;
void modify(Node* t, int l, int r) {
if(l == r) {
if(type == 1 && !t->s) t->s = true;
if(type == 2 && t->s) t->s = false;
} else {
int m = M(l, r);
v <= m ? modify(t->l, l, m) : modify(t->r, m + 1, r);
t->update();
}
}
int query(Node* t, int l, int r) {
if(!t->s) return 0;
if(l == r) return l;
int m = M(l, r);
return type == 3 ? (t->l->s ? query(t->l, l, m) : query(t->r, m + 1, r)) :
(t->r->s ? query(t->r, m + 1, r) : query(t->l, l, m));
}
int succ(Node* t, int l, int r) {
if(!t->s) return 0;
if(l == r) return l <= v ? 0 : l;
int m = M(l, r);
if(v >= m) return succ(t->r, m + 1, r);
int ans = succ(t->l, l, m);
return ans ? ans : succ(t->r, m + 1, r);
}
int pred(Node* t, int l, int r) {
if(!t->s) return 0;
if(l == r) return l >= v ? 0 : l;
int m = M(l, r);
if(m + 1 >= v) return pred(t->l, l, m);
int ans = pred(t->r, m + 1, r);
return ans ? ans : pred(t->l, l, m);
}
int find(Node* t, int l, int r) {
if(!t->s) return -1;
if(l == r) return 1;
int m = M(l, r);
return v <= m ? find(t->l, l, m) : find(t->r, m + 1, r);
}
inline void read(int &t) {
t = 0;
char c = getchar();
for(; !isdigit(c); c = getchar());
for(; isdigit(c); c = getchar())
t = t * 10 + c - ‘0‘;
}
int main() {
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
int m;
cin >> n >> m;
n++;
build(root = pt++, 1, n);
while(m--) {
read(type);
switch(type) {
case 1 : read(v); v++; modify(root, 1, n); break;
case 2 : read(v); v++; modify(root, 1, n); break;
case 3 : printf("%d\n", query(root, 1, n) - 1); break;
case 4 : printf("%d\n", query(root, 1, n) - 1); break;
case 5 : read(v); v++; printf("%d\n", pred(root, 1, n) - 1); break;
case 6 : read(v); v++; printf("%d\n", succ(root, 1, n) - 1); break;
case 7 : read(v); v++; printf("%d\n", find(root, 1, n)); break;
default : break;
}
}
return 0;
}
------------------------------------------------------------------------------------------
3685: 普通van Emde Boas树
Time Limit: 9 Sec Memory Limit: 128 MB
Submit: 616 Solved: 216
[Submit][Status][Discuss]Description
设计数据结构支持:
1 x 若x不存在,插入x
2 x 若x存在,删除x
3 输出当前最小值,若不存在输出-1
4 输出当前最大值,若不存在输出-1
5 x 输出x的前驱,若不存在输出-1
6 x 输出x的后继,若不存在输出-1
7 x 若x存在,输出1,否则输出-1
Input
第一行给出n,m 表示出现数的范围和操作个数
接下来m行给出操作
n<=10^6,m<=2*10^6,0<=x<n
Output
Sample Input
10 11
1 1
1 2
1 3
7 1
7 4
2 1
3
2 3
4
5 3
6 2
Sample Output
1
-1
2
2
2
-1
HINT
Source
BZOJ 3685: 普通van Emde Boas树( 线段树 )
标签:
原文地址:http://www.cnblogs.com/JSZX11556/p/4666047.html