4320: ShangHai2006 Homework
Time Limit: 10 Sec Memory Limit: 128 MBDescription
1:在人物集合 S 中加入一个新的程序员,其代号为 X,保证 X 在当前集合中不存在。
2:在当前的人物集合中询问程序员的mod Y 最小的值。 (为什么统计这个?因为拯救
过世界的人太多了,只能取模)
Input
第一行为用空格隔开的一个个正整数 N。
接下来有 N 行,若该行第一个字符为“A” ,则表示操作 1;若为“B”,表示操作 2;
其中 对于 100%的数据:N≤100000, 1≤X,Y≤300000,保证第二行为操作 1。
Output
对于操作 2,每行输出一个合法答案。
Sample Input
5
A 3
A 5
B 6
A 9
B 4
A 3
A 5
B 6
A 9
B 4
Sample Output
3
1
1
HINT
【样例说明】
在第三行的操作前,集合里有 3、5 两个代号,此时 mod 6 最小的值是 3 mod 6 = 3;
在第五行的操作前,集合里有 3、5、9,此时 mod 4 最小的值是 5 mod 4 = 1;
Source
对于小于logN的暴力,对于大于logN的每次查询k*Y的后继
听说set会被卡,所以上了splay……
#include <iostream>
#include <cstdio>
#include <cmath>
#include <set>
#include <climits>
#include <cstring>
#include <algorithm>
using namespace std;
const int SZ = 300010;
const int INF = 1e9 + 10;
struct node
{
node *ch[2], *f;
int sz, cnt, v;
void maintain()
{
sz = cnt + ch[0] -> sz + ch[1] -> sz;
}
int cmp(int x)
{
if(x == v) return -1;
return x < v ? 0 : 1;
}
int dir()
{
return f -> ch[1] == this;
}
void setc(node *x, int d)
{
(ch[d] = x) -> f = this;
}
}T[SZ], *root, *null;
int Tcnt = 0;
int num[SZ], m[SZ];
void read_int(int &num)
{
num = 0;
int f = 1;
char c = getchar();
while(c < '0' || c > '9')
{
if(c == '-') f = -1;
c = getchar();
}
while('0' <= c && c <= '9')
{
num= num * 10 + (c - '0');
c = getchar();
}
num *= f;
}
void read_operation(int &op)
{
char c = getchar();
while(c != 'A' && c != 'B')
c = getchar();
op = c == 'A' ? 1 : 2;
}
node* newnode(int x, node *f)
{
node *k = T + (++Tcnt);
k -> v = x;
k -> ch[0] = k -> ch[1] = null;
k -> sz = k -> cnt = 1;
k -> f = f;
return k;
}
void rotate(node *p)
{
node *fa = p -> f;
int d = p -> dir();
fa -> f -> setc(p, fa -> dir());
fa -> setc(p -> ch[d ^ 1], d);
fa -> maintain();
p -> setc(fa, d ^ 1);
p -> maintain();
if(fa == root) root = p;
}
void splay(node *p, node *rt = null)
{
while(p -> f != rt)
{
if(p -> f -> f == rt)
rotate(p);
else
{
if(p -> dir() == p -> f -> dir())
rotate(p -> f), rotate(p);
else rotate(p), rotate(p);
}
}
p -> maintain();
}
void insert(node *p, int x)
{
if(root == null)
{
root = newnode(x, null);
return ;
}
while(p != null)
{
p -> sz++;
int d = p -> cmp(x);
if(d == -1)
{
p -> cnt++;
break;
}
if(p -> ch[d] == null)
{
p -> ch[d] = newnode(x, p);
p = p -> ch[d];
break;
}
p = p -> ch[d];
}
splay(p);
}
int ask_suf(node *p, int x)
{
int ans = 0;
while(p != null)
{
if(p -> v > x) ans = p -> v, p = p -> ch[0];
else if(p -> v == x) return p -> v;
else p = p -> ch[1];
}
return ans;
}
void init()
{
null = newnode(-INF, null);
null -> sz = null -> cnt = 0;
root = null;
}
int main()
{
init();
int n, op, ss, cnt = 0;
int max_element = 0;
read_int(n);
int end = sqrt(300000);
for(int i = 1; i <= end; i++)
num[i] = INT_MAX;
char s[5];
while(n--)
{
read_operation(op);
read_int(ss);
if(op == 1)
{
insert(root, ss);
for(int i = 1; i <= end; i++)
num[i] = min(num[i], ss % i);
max_element = max(max_element, ss);
}
else
{
if(ss <= end) printf("%d\n", num[ss]);
else
{
int minn = INT_MAX;
int find_element = 0;
while(find_element <= max_element)
{
int the_element = ask_suf(root, find_element);
minn = min(minn, the_element % ss);
find_element += ss;
}
printf("%d\n", minn);
}
}
}
return 0;
}