题目:
题解:
set用来维护哪几个房间有人,在区间操作时可以直接跳转
map判重
hash表判断这个房间里的团体有没有经验值
代码:
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#define ull unsigned long long
using namespace std;;
const int N=1e5;
const ull p=1310000001ull;
set<int>s;
map<ull,bool>mp;
ull mi[N+5],hah[N+5];
int cnt[N+5],loc[N+5];
int main()
{
int n,m,q,i;
scanf("%d%d%d",&n,&m,&q);
mi[0]=1;
for (i=1;i<=n;i++)
{
mi[i]=mi[i-1]*p;
hah[1]+=(ull)i*mi[i];
loc[i]=1;
}
s.insert(0); s.insert(m+1); s.insert(1);
cnt[1]=n;
while (q--)
{
char st[5];int l,r;
scanf("%s",st);scanf("%d%d",&l,&r);
if (st[0]=='C')
{
cnt[loc[l]]--;cnt[r]++;
s.erase(loc[l]); s.erase(r);
hah[loc[l]]-=(ull)l*mi[l];
hah[r]+=(ull)l*mi[l];
if (!mp[hah[loc[l]]]) s.insert(loc[l]);
if (!mp[hah[r]]) s.insert(r);
loc[l]=r;
}
else
{
set<int>::iterator it,ll,rr;
int ans=0;
ll=s.lower_bound(l); rr=s.upper_bound(r);
for (it=ll;it!=rr;it=s.lower_bound(l))
{
mp[hah[*it]]=1;
ans+=cnt[*it];
s.erase(it);
}
printf("%d\n",ans);
}
}
}