记录编号 359767 评测结果 AAAAAAATTA
题目名称 [SHOI 2008]堵塞的交通traffic 最终得分 80
用户昵称 GravatarAntiLeaf 是否通过 未通过
代码语言 C++ 运行时间 3.526 s
提交时间 2016-12-24 18:12:44 内存使用 20.14 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<vector>
  5. #include<map>
  6. using namespace std;
  7. const int maxn=100010;
  8. inline int randint(){
  9. static int a=151,b=24863,c=9788417,x=1089488183,p=998244353;
  10. x=a*x*x+b*x+c;x%=p;
  11. return x<0?(x=-x):x;
  12. }
  13. struct A{int u,v,tp;}a[maxn];
  14. void addedge(int,int,int);
  15. void addquery(int,int,int);
  16. void solve(int,int,int);
  17. int findroot(int);
  18. void mergeset(int,int,vector<int>&);
  19. int id[3][maxn],cnt=0,prt[maxn<<1],qu[maxn<<2],qv[maxn<<2];
  20. int n,m=1,x1,y1,x2,y2,x,y,s,t;
  21. vector<int>u[maxn<<2],v[maxn<<2],stk[maxn<<2];
  22. map<pair<int,int>,int>mp;
  23. char c[15];
  24. int main(){
  25. freopen("bzoj_1018.in","r",stdin);
  26. freopen("bzoj_1018.out","w",stdout);
  27. scanf("%d",&n);
  28. for(int i=1;i<=n;i++){
  29. id[1][i]=++cnt;
  30. id[2][i]=++cnt;
  31. }
  32. for(int i=1;i<=cnt;i++)prt[i]=i;
  33. for(int &i=m;scanf("%s",c)==1&&strcmp(c,"Exit");i++){
  34. scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
  35. x=id[x1][y1];y=id[x2][y2];
  36. if(x>y)swap(x,y);
  37. a[i].u=x;a[i].v=y;
  38. if(!strcmp(c,"Open"))a[i].tp=1;
  39. else if(!strcmp(c,"Close"))a[i].tp=2;
  40. else a[i].tp=3;
  41. }
  42. for(int i=1;i<=m;i++){
  43. x=a[i].u;y=a[i].v;
  44. if(a[i].tp==1){
  45. if(!mp.count(make_pair(x,y)))mp[make_pair(x,y)]=i;
  46. }
  47. else if(a[i].tp==2){
  48. if(mp.count(make_pair(x,y))){
  49. s=mp[make_pair(x,y)];
  50. t=i;
  51. addedge(1,m,1);
  52. mp.erase(make_pair(x,y));
  53. }
  54. }
  55. else{
  56. t=i;
  57. addquery(1,m,1);
  58. }
  59. }
  60. for(map<pair<int,int>,int>::iterator it=mp.begin();it!=mp.end();it++){
  61. x=it->first.first;
  62. y=it->first.second;
  63. s=it->second;
  64. t=m;
  65. addedge(1,m,1);
  66. }
  67. solve(1,m,1);
  68. return 0;
  69. }
  70. void addedge(int l,int r,int rt){
  71. if(s<=l&&t>=r){
  72. u[rt].push_back(x);
  73. v[rt].push_back(y);
  74. return;
  75. }
  76. int mid=(l+r)>>1;
  77. if(s<=mid)addedge(l,mid,rt<<1);
  78. if(t>mid)addedge(mid+1,r,rt<<1|1);
  79. }
  80. void addquery(int l,int r,int rt){
  81. if(l==r){
  82. qu[rt]=x;
  83. qv[rt]=y;
  84. return;
  85. }
  86. qu[rt]|=x;
  87. int mid=(l+r)>>1;
  88. if(t<=mid)addquery(l,mid,rt<<1);
  89. else addquery(mid+1,r,rt<<1|1);
  90. }
  91. void solve(int l,int r,int rt){
  92. if(!qu[rt])return;
  93. for(int i=0;i<(int)u[rt].size();i++)mergeset(u[rt][i],v[rt][i],stk[rt]);
  94. if(l==r)printf(findroot(qu[rt])==findroot(qv[rt])?"Y\n":"N\n");
  95. else{
  96. int mid=(l+r)>>1;
  97. solve(l,mid,rt<<1);
  98. solve(mid+1,r,rt<<1|1);
  99. }
  100. if(!stk[rt].empty())for(int i=(int)stk[rt].size()-1;i>=0;i--)prt[stk[rt][i]]=stk[rt][i];
  101. }
  102. int findroot(int x){
  103. while(prt[x]!=x)x=prt[x];
  104. return x;
  105. }
  106. void mergeset(int x,int y,vector<int>&a){
  107. x=findroot(x);y=findroot(y);
  108. if(x==y)return;
  109. if(randint()&1)swap(x,y);
  110. prt[x]=y;
  111. a.push_back(x);
  112. }