【bzoj 3578】 GTY的人类基因组计划2(STL的应用)

来源:互联网 发布:数控冲床编程教学 编辑:程序博客网 时间:2024/06/05 20:08

3578: GTY的人类基因组计划2

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 323  Solved: 145
[Submit][Status][Discuss]

Description

  GTY召唤了n个人来做实验,GTY家的房子很大,有m个房间一开始所有人都在1号房间里,GTY会命令某人去某个房间等待做实验,或者命令一段区间的房间开始实验,实验会获得一些实验信息点数,点数为房间里的人数,如果一个房间里的一群人已经做过实验了那么这些人将不会增加实验信息点数(不会增加是针对这一群人的,不是对这群人中的每个人,即1,2,3做了实验,1,2再做实验还会增加2点实验点数)

Input

第一行两个整数n,m,q(n,m,q<=10^5)表示人数,房间数和操作数
接下来q行每行一个操作 "C i j"表示让第i个人去房间j "W l r" 表示让区间[l,r]的房间做实验

Output

对于每一个W操作,输出一个数,表示此次操作所获得的实验点数

Sample Input

3 5 7
C 1 2
C 2 2
W 1 2
C 3 2
W 1 2
C 3 3
W 1 3

Sample Output

3
3
0

HINT

善用STL

Source

By orzpzmaimeng

[Submit][Status][Discuss]



【题解】【STL的应用,一改往常一用STL就荣获TLE的经历啊,看来以前还是使用的不够优越】

【这道题,先给所有的人随机一个值,因为是给一个集合判重,所以判重的时候,将几个人的值异或起来,用map判断是否出现过;将每一次移动后合法的集合即房间号存在set里,每一次移动时,先将相关的两个房间的序号先从set里删掉,再将合法的加入。

  记录:每个房间的人数,每个人的编号,每个房间的当前异或值。】


#include<map>#include<set>#include<ctime>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;set<int>s;//存合法的房间号 map<long long,bool>mp;//判重 long long  num[100010],p[1000010],b[1000010],h[1000010];int n,m,q;int main(){int i,j;srand(1289);scanf("%d%d%d\n",&n,&m,&q);for(i=1;i<=n;++i) num[i]=(long long)rand()*rand()%1000000000*(rand()*rand()%2000000000);//给每个人随机一个值 s.insert(1);//因为刚开始所有人都在第一个房间,先将第一个房间加入set for(i=1;i<=n;++i) h[1]^=num[i],p[1]++,b[i]=1;//h存当前房间的异或值;p存当前房间的人数;b存当前每个人在哪个房间 for(i=1;i<=q;++i)//询问和操作总共不超过10^5,且每次操作只移动一个人,所以范围可以使用STL  {    char c; int x,y; scanf("%c",&c); scanf("%d%d\n",&x,&y); if(c=='C')   {   if(b[x]==y) continue;//看操作后是否换了房间    s.erase(b[x]); s.erase(y);//将原来的状态移出set         h[b[x]]^=num[x];     p[b[x]]--;     if (!mp[h[b[x]]]) s.insert(b[x]);          h[y]^=num[x];     p[y]++;     if (!mp[h[y]]) s.insert(y);          b[x]=y;   }  else   if(c=='W')    {      int ans=0; set<int>::iterator it=s.lower_bound(x); for(;it!=s.end()&&*it<=y;it=s.lower_bound(x))  {  mp[h[*it]]=1;  ans+=p[*it];  s.erase(it);  } printf("%d\n",ans);   } } return 0;}


0 0
原创粉丝点击