 /**//*
n<=10^9个位置, q<=10^5个操作
操作有三种
(1)插入
选择靠右的最长空白的一段,然后插入到中间(若长度为偶数,是指靠右的那个中间位置)
(2)删除
(3)查询一段中的已插入点个数

我一开始想线段树,搞不出 ,主要是那些点不确定
看了shik的代码,神奇丫

树状数组的数组可以用map<int,int>来做,解决了空间问题!!!
用set<Segment>来存储可用的线段
然后需要再加多一个set记录所有分割点,这个很重要,我当时没想到这个 #_#

然后就是维护上面3个主要的数据结构了
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<set>
#include<list>
#include<numeric>
#include<cassert>
#include<ctime>
#include<bitset>

using namespace std;

 struct Segment {
int st, ed;
 Segment(int st, int ed) : st(st), ed(ed) {
}
};

 inline bool operator < (const Segment & A, const Segment &B) {
 if(A.ed - A.st != B.ed - B.st) {
return A.ed - A.st > B.ed - B.st;
}
return A.st > B.st;
}

map<int, int> C;
int n, q;

 inline int lowbit(int x) {
return x & (-x);
}

 void insert(int x , int val) {
 while(x <= n) {
C[x] += val;
x += lowbit(x);
}
}

 int query(int x) {
map<int,int>::iterator it;
int ans = 0;
 while(x > 0) {
// ans += C[x]; 不要直接这样,需要先查找一下,不存在的不用加,快很多!!!
 if((it = C.find(x)) != C.end()) {
ans += it->second;
}
x -= lowbit(x);
}
return ans;
}

 int query(int x, int y) {
return query(y) - query(x-1);
}

int main()
  {
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif
 for (; ~scanf("%d%d", &n, &q); ) {
C.clear();
set<Segment> iset;
iset.insert(Segment(1,n));
set<int> pt;
pt.insert(0);
pt.insert(n+1);
map<int,int> mp;

int p, st, ed;
 while(q--) {
scanf("%d", &p);
 if(p == 0) {
scanf("%d%d", &st, &ed);
printf("%d\n", query(st,ed));
 } else {
 if(mp[p] == 0) {
set<Segment>::iterator it = iset.begin();
st = it->st, ed = it->ed;
iset.erase(it);
int m = (st+ed+1) / 2;
mp[p] = m;
pt.insert(m);
insert(m,1);
 if(st <= m - 1) {
iset.insert(Segment(st,m-1));
}
 if(m+1 <= ed) {
iset.insert(Segment(m+1,ed));
}
 } else {
int m = mp[p];
mp[p] = 0;
set<int>::iterator left, right, it;
 /**//*
left = pt.lower_bound(m);
left--;
right = pt.upper_bound(m);
pt.erase(m);
*/
left = right = it = pt.find(m);
left --;
right++;
pt.erase(it);
insert(m,-1);
st = (*left)+1;
ed = (*right)-1;
 if(st <= m - 1) {
iset.erase(Segment(st, m-1));
}
 if(m+1 <= ed) {
iset.erase(Segment(m+1,ed));
}
 if(st <= ed) {
iset.insert(Segment(st,ed));
}
}
}
}
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|