BZOJ 3578 GTY的人类基因组计划2 set

题目大意:有一些人一开始都在一号房间。有一些指令使他们区别的房间。每次选定一段区间作试验,如果有的房间的组合已经做过试验,那么就不计入最后的试验点数,否则计入试验点数为试验的人数。问最后会获得多少试验点数。


思路:对于每一个人随即一个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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值