| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
若在HDU上错了,在POJ上过了,可以看看这个信息给个样例
8 2333
D 2
D 4
D 2
R
Q 1 //这个查询应该是在hdu是3,在POJ上是3或1都能过。我亲测的。两个OJ的测试数据不同。同一个村庄可能摧毁几次,修复一次,是否可以把前些次D操作全修好呢?
下面是两个OJ都可以AC的代码
#include <iostream>
#include <cstring>
using namespace std;
const int N = 50007;
int bit[N], n, s[N];
bool vis[N];
inline int lowbit(int x) {
return x & -x;
}
void add(int pos, int val) {
for (int i = pos; i <= n; i += lowbit(i))
bit[i] += val;
}
int sum(int pos) {
int res = 0;
for (int i = pos; i > 0; i -= lowbit(i))
res += bit[i];
return res;
}
int main()
{
ios::sync_with_stdio(false);
int q;
while (cin >> n >> q) {
memset(bit, 0, sizeof bit);
memset(vis, 1, sizeof vis);
int cur = 0;
for (int i = 1; i <= n; ++i) //这一步有点耗时,若能把0看做连通,1看做非连通,初始全为0可以用memset
add(i, 1);
char opt; int x = 0;
while (q--) {
cin >> opt; if (opt != 'R') cin >> x;
if (opt == 'D') {
s[cur++] = x;
if (vis[x]) {
vis[x] = false;
add(x, -1);
}
}
else if (opt == 'R') {
if (cur > 0) {
x = s[--cur];
add(x, 1);
vis[x] = true;
}
}
else if (opt == 'Q') {
if (!vis[x]) {
cout << 0 << endl;
continue;
}
int tmp = sum(x), a = 1, b = n;
int l = 0, r = x; //左侧连通数
while (l <= r) {
int m = l + r >> 1;
if (tmp - sum(m) == x - m) {
a = m + 1;
r = m - 1;
}
else l = m + 1;
}
l = x, r = n;
while (l <= r) {
int m = l + r >> 1;
if (sum(m) - tmp == m - x) {
b = m;
l = m + 1;
}
else r = m - 1;
}
cout << b - a + 1 << endl;
}
}
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator