题解 P2087 【GTY的人类基因组计划2】
这题没有题解??做的人太少了。。
为什么标签是平衡树和线段树。。。
自己完全是按照提示全STL水过的啊 set map就好了。
这题开始能想到一些思路,但是不懂怎么hash。。
现在知道集合hash可以用xor的啊~
先随机一个long long范围的数字,之后xor就是整个集合的hash值了。。
听说用妹子生日做srand()的种子会有神秘加成
代码:
#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define uLL unsigned long long
#define MAXN 0x186AF
map<uLL,bool> hash;
set<int> zt;
uLL h[MAXN],an[MAXN],size[MAXN];
int at[MAXN];
char ch[8];
int main(){
freopen("input2.txt","r",stdin);
freopen("input2.out","w",stdout);
srand(2001+06+28); //这个数多少不重要啦,不小心被卡就换个就行了。。
int n,m,q; cin>>n>>m>>q;
for(int i=1;i<=n;i++){
int k1=rand()<<16|rand()%1000000000,
k2=rand()<<16|rand()%2000000000;
an[i]=(uLL)k1*k2; h[1]^=an[i]; at[i]=1; //蜜汁hash
}
hash.clear(); zt.insert(1); size[1]=n;
for(int i=1;i<=q;i++){
int x,y; scanf("%s%d%d",ch,&x,&y);
if(ch[0]=='C'){
if(at[x]==y) continue;
zt.erase(at[x]); zt.erase(y);
h[at[x]]^=an[x]; size[at[x]]--;
if(!hash[h[at[x]]]) zt.insert(at[x]);
at[x]=y; h[y]^=an[x]; size[y]++;
if(!hash[h[y]]) zt.insert(y); //直接模拟,有重复的就删
}
else{
int ans=0;
set<int>::iterator it=zt.lower_bound(x);
for(;it!=zt.end()&&*it<=y;it=zt.lower_bound(x)){
ans+=size[*it]; hash[h[*it]]=1; zt.erase(it);
} //把满足条件的i都加上 (x<=i<=y)
printf("%d\n", ans);
}
}
}
其实出题人不想让我们这么水的是么