multiset运用 HDU 1540 Tunnel Warfare

来源:互联网 发布:网络同传多台机器变慢 编辑:程序博客网 时间:2024/05/16 04:25

用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);elseinsert(x, pre * 2 + 1);if(node[pre * 2].leftD != -1)node[pre].leftD = node[pre * 2].leftD;elsenode[pre].leftD = node[pre * 2 + 1].leftD;if(node[pre * 2 + 1].rightD != -1)node[pre].rightD = node[pre * 2 + 1].rightD;elsenode[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);elseerase(x, pre * 2 + 1);if(node[pre * 2].leftD != -1)node[pre].leftD = node[pre * 2].leftD;elsenode[pre].leftD = node[pre * 2 + 1].leftD;if(node[pre * 2 + 1].rightD != -1)node[pre].rightD = node[pre * 2 + 1].rightD;elsenode[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);elsereturn 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);elsereturn 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");elseprintf("%d\n", findRight(a, 1) - findLeft(a, 1) - 1);}}}return 0;}