• [SHOI2008]堵塞的交通traffic


    我是萌萌的传送门

    这题说白了就是一个支持加边和删边的图连通性维护,不过鉴于图的特殊性,可以直接线段树(听说标算就是这个……)。

    然而我人比较懒,不想思考怎么线段树,于是乎写了一发分治并查集,1A我真是感动……

    话说一时没想起来怎么写能撤销的按秩合并,于是乎写了个随机合并(反正期望复杂度都是logn的),代码开头那个玩意儿就是手写的随机数生成器……(我会说模数取998244353之后即使int有溢出也能保证循环节在一千万以上嘛……)

    第一发分治并查集,又学会了一个新技能哈哈……

    话说这份代码在bzoj上被卡了,真是忧伤……

      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
    ");
     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 }
    View Code

    不知道该加什么分类了,反正是对时间建线段树,加到CDQ分治里算了……

  • 相关阅读:
    第九篇装饰器基本原理
    第八篇迭代器协议和生产器
    python第六篇文件处理类型
    Python开发【第十篇】:模块
    习题练习
    2.2.6 集合
    第七篇 python基础之函数,递归,内置函数
    Python开发【第五篇】:Python基础之杂货铺
    Python开发【第四篇】:Python基础之函数
    详解CSS position属性
  • 原文地址:https://www.cnblogs.com/hzoier/p/6218128.html
Copyright © 2020-2023  润新知