用multiset集合类的时候要包含
#include<stdlib.h>
#include<set>
#include<iostream>
using namespace std;
以上一个都不能少
multiset<type, compare>
默认compare为升序,而且只有重载了<操作符的才能正常运用
对于其他类型,我们就要自定义compare结构体
struct cmp
{
bool operator()(const int& a, const int& b)const
{
return a > b;
}
};
这是一个升序结构体,bool operator()(const int& a, const int& b)const,const和括号都不能少,否则编译不过,因为可能集合类里面的函数指针不匹配
对于HDU 1540,我用两个集合类,一个升序,一个降序,每次求与该村庄x相连的村庄个数时,我们只需要求出左边最靠近x的被摧毁村庄y和右边最靠近x的被摧毁村庄z
z - y - 1及为与x相连的村庄个数(包括x本身),其中z,y都不能与x相同,否则x已经被摧毁,答案为0
我的代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<set>
#include<iostream>
using namespace std;
int n, q;
int stack[50001], snum;
multiset<int> myset1;
multiset<int>::iterator it1;
struct cmp
{
bool operator()(const int& a, const int& b)const
{
return a > b;
}
};
multiset<int, cmp> myset2;
multiset<int, cmp>::iterator it2;
int main()
{
int i, a, temp;
char str[3];
while(scanf("%d%d", &n, &q) != EOF)
{
myset1.clear();
myset1.insert(0);
myset1.insert(n + 1);
myset2.clear();
myset2.insert(0);
myset2.insert(n + 1);
snum = 0;
for(i = 1; i <= q; i ++)
{
scanf("%s", str);
if(str[0] == 'D')
{
scanf("%d", &a);
myset1.insert(a);
myset2.insert(a);
stack[++ snum] = a;
}
else if(str[0] == 'R')
{
if(snum >= 1)
{
myset1.erase(stack[snum]);
myset2.erase(stack[snum]);
snum --;
}
}
else
{
scanf("%d", &a);
it1 = myset1.lower_bound(a);
temp = *it1;
if(temp == a)
{
printf("0\n");
continue;
}
it2 = myset2.lower_bound(a);
printf("%d\n", temp - *it2 - 1);
}
}
}
return 0;
}
线段树做法代码
#include<stdio.h>
#include<string.h>
struct Node
{
int leftD;
int rightD;
int left;
int right;
}node[210001];
int n, m;
int stack[51001], snum;
int instack[51001];
int build(int left, int right, int pre)
{
int mid = (left + right) / 2;
node[pre].left = left;
node[pre].right = right;
node[pre].leftD = -1;
node[pre].rightD = -1;
if(left == right)
return 0;
build(left, mid, pre * 2);
build(mid + 1, right, pre * 2 + 1);
return 0;
}
int insert(int x, int pre)
{
int mid = (node[pre].left + node[pre].right) / 2;
if(node[pre].left == node[pre].right)
{
node[pre].leftD = x;
node[pre].rightD = x;
return 0;
}
if(x <= mid)
insert(x, pre * 2);
else
insert(x, pre * 2 + 1);
if(node[pre * 2].leftD != -1)
node[pre].leftD = node[pre * 2].leftD;
else
node[pre].leftD = node[pre * 2 + 1].leftD;
if(node[pre * 2 + 1].rightD != -1)
node[pre].rightD = node[pre * 2 + 1].rightD;
else
node[pre].rightD = node[pre * 2].rightD;
return 0;
}
int erase(int x, int pre)
{
int mid = (node[pre].left + node[pre].right) / 2;
if(node[pre].left == node[pre].right)
{
node[pre].leftD = -1;
node[pre].rightD = -1;
return 0;
}
if(x <= mid)
erase(x, pre * 2);
else
erase(x, pre * 2 + 1);
if(node[pre * 2].leftD != -1)
node[pre].leftD = node[pre * 2].leftD;
else
node[pre].leftD = node[pre * 2 + 1].leftD;
if(node[pre * 2 + 1].rightD != -1)
node[pre].rightD = node[pre * 2 + 1].rightD;
else
node[pre].rightD = node[pre * 2].rightD;
return 0;
}
int findRight(int x, int pre)
{
int mid = (node[pre].left + node[pre].right) / 2;
if(node[pre].left == node[pre].right)
{
int temp = pre / 2;
while(1)
{
if(pre == temp * 2 && node[pre + 1].leftD != -1)
return node[pre + 1].leftD;
pre = temp;
temp = pre / 2;
}
return 0;
}
if(x <= mid)
return findRight(x, pre * 2);
else
return findRight(x, pre * 2 + 1);
return 0;
}
int findLeft(int x, int pre)
{
int mid = (node[pre].left + node[pre].right) / 2;
if(node[pre].left == node[pre].right)
{
int temp = pre / 2;
while(1)
{
if(pre == temp * 2 + 1 && node[pre - 1].rightD != -1)
return node[pre - 1].rightD;
pre = temp;
temp = pre / 2;
}
return 0;
}
if(x <= mid)
return findLeft(x, pre * 2);
else
return findLeft(x, pre * 2 + 1);
return 0;
}
int main()
{
char str[10];
int a;
int i;
while(scanf("%d%d", &n, &m) != EOF)
{
snum = 0;
build(0, n + 1, 1);
insert(0, 1);
insert(n + 1, 1);
memset(instack, 0, sizeof(instack));
for(i = 1; i <= m; i ++)
{
scanf("%s", str);
if(str[0] == 'D')
{
scanf("%d", &a);
insert(a, 1);
instack[a] = 1;
stack[++ snum] = a;
}
else if(str[0] == 'R')
{
if(snum > 0)
{
erase(stack[snum], 1);
instack[stack[snum]] = 0;
snum --;
}
}
else
{
scanf("%d", &a);
if(instack[a])
printf("0\n");
else
printf("%d\n", findRight(a, 1) - findLeft(a, 1) - 1);
}
}
}
return 0;
}