zoukankan      html  css  js  c++  java
  • [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分治里算了……

  • 相关阅读:
    防删没什么意思啊,直接写废你~
    绝大多数情况下,没有解决不了的问题,只有因为平时缺少练习而惧怕问题的复杂度,畏惧的心理让我们选择避让,采取并不那么好的方案去解决问题
    Java 模拟面试题
    Crossthread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on
    一步步从数据库备份恢复SharePoint Portal Server 2003
    【转】理解 JavaScript 闭包
    Just For Fun
    The database schema is too old to perform this operation in this SharePoint cluster. Please upgrade the database and...
    Hello World!
    使用filter筛选刚体碰撞
  • 原文地址:https://www.cnblogs.com/hzoier/p/6218128.html
Copyright © 2011-2022 走看看