题目大意:有一些人一开始都在一号房间。有一些指令使他们区别的房间。每次选定一段区间作试验,如果有的房间的组合已经做过试验,那么就不计入最后的试验点数,否则计入试验点数为试验的人数。问最后会获得多少试验点数。
思路:对于每一个人随即一个long long,一个集合所代表的数字就是这些long long的异或和。然后用set来暴力判重。
CODE:
#include <set> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 100010 using namespace std; int points,cnt,asks; unsigned long long src[MAX]; char c[10]; int size[MAX],_in[MAX]; set<unsigned long long> used; set<int> status; unsigned long long now[MAX]; int main() { srand(19970806); cin >> points >> cnt >> asks; for(int i = 1; i <= points; ++i) { src[i] = (unsigned long long)rand() * rand() * rand(); now[1] ^= src[i]; _in[i] = 1; } size[1] = points; status.insert(1); for(int x,y,i = 1; i <= asks; ++i) { scanf("%s%d%d",c,&x,&y); if(c[0] == 'C') { size[_in[x]]--; size[y]++; if(status.find(_in[x]) != status.end()) status.erase(_in[x]); if(status.find(y) != status.end()) status.erase(y); now[_in[x]] ^= src[x]; now[y] ^= src[x]; if(used.find(now[_in[x]]) == used.end()) status.insert(_in[x]); if(used.find(now[y]) == used.end()) status.insert(y); _in[x] = y; } else { static set<int>::iterator it; int ans = 0; it = status.lower_bound(x); for(;it != status.end() && *it <= y;) { ans += size[*it]; used.insert(now[*it]); status.erase(it); it = status.lower_bound(x); } printf("%d\n",ans); } } return 0; }
时间: 2024-10-29 00:57:02