3578: GTY的人类基因组计划2
第一次居然hash被卡了。改了改rd()就A了。
题解:咱给每个人都随机一个数,几个人就是把他们的数异或起来,用set判重。再开一个set记录合法的房间。
1 #include<set> 2 #include<cstdio> 3 #include<bitset> 4 #include<cstdlib> 5 #include<iostream> 6 using namespace std; 7 inline char nc() { 8 static char b[1<<16],*s=b,*t=b; 9 return s==t&&(t=(s=b)+fread(b,1,1<<16,stdin),s==t)?-1:*s++; 10 } 11 inline void read(int &x) { 12 char b = nc(); x = 0; 13 for (; !isdigit(b); b = nc()); 14 for (; isdigit(b); b = nc()) x = x * 10 + b - ‘0‘; 15 } 16 inline int op() { 17 char b = nc(); for (; b != ‘C‘ && b != ‘W‘; b = nc()); return b == ‘C‘; 18 } 19 typedef unsigned long long ull; 20 typedef ull bt; 21 int n, m, q, p[100005], c[100005]; 22 const ull ULL_MAX = -1; 23 bt a[100005], b[100005]; 24 inline ull rd() { 25 return ull(rand()) * rand() * rand(); 26 } 27 set < bt > h; 28 set < int > s; 29 int main() { 30 read(n); read(m); read(q); srand(89513255); s.insert(1); 31 for (int i = 1; i <= n; ++i) a[i] = rd(), p[i] = 1; 32 for (int i = 1; i <= n; ++i) b[1] ^= a[i]; c[1] = n; 33 for (int l, r, o, i = 0; i < q; ++i) { 34 o = op(); read(l); read(r); 35 if (o) { 36 if (p[l] == r) continue; 37 s.erase(p[l]); s.erase(r); 38 b[p[l]] ^= a[l]; --c[p[l]]; 39 if (!h.count(b[p[l]])) s.insert(p[l]); 40 b[r] ^= a[l]; ++c[r]; p[l] = r; 41 if (!h.count(b[r])) s.insert(r); 42 } else { 43 int ans = 0; static set < int > :: iterator it; it = s.lower_bound(l); 44 for (; it != s.end() && *it <= r; it = s.lower_bound(l)) { 45 h.insert(b[*it]); ans += c[*it]; s.erase(it); 46 } printf("%d\n", ans); 47 } 48 } 49 return 0; 50 }