• [cf1217F]Forced Online Queries Problem


    可以用并查集维护连通性,删除可以用按置合并并查集,但删掉一条边后无法再维护两点的联通性了(因为产生环的边是不加入的)
    暴力思路是, 考虑前i个操作后边的集合,暴力加入即可,但复杂度是$o(n^2)$的
    用分块,对于每一个块,先求出前面所有块操作后边的集合,去掉这个块内删掉的边,这个并查集一定是之后这个块内每一个点都有的并查集,即计算每一个点时都恢复到这个并查集(恢复时记录下修改的点,因此也不能路径压缩)
    之后用暴力的做法,这个集合大小是$o(sqrt{n})$的,那么总复杂度就是$o(nsqrt{n})$,可以通过
    (这个算法是离线,因为它需要之后那个块内的操作,但这些操作最多只会衍生出两种操作,只要存在一个就都不要放入原并查集中即可)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define K 5000
     4 #define N 200005
     5 #define pii pair<int,int>
     6 #define fi first
     7 #define se second
     8 int n,m,ans,p[N],x[N],y[N],f[N],g[N],sz[N],v1[N];
     9 pii v2[N];
    10 set<pii>g1,g2;
    11 set<pii>::iterator it;
    12 int find(int k){
    13     if (k==f[k])return k;
    14     return find(f[k]);
    15 }
    16 void check(int x,int y){
    17     if (x>y)swap(x,y);
    18     pii o=make_pair(x,y);
    19     if (g1.find(o)!=g1.end()){
    20         g1.erase(o);
    21         g2.insert(o);
    22     }
    23 }
    24 void update(pii o){
    25     if (g2.find(o)==g2.end())g2.insert(o);
    26     else g2.erase(o);
    27 }
    28 void add(int x,int y){
    29     x=find(x);
    30     y=find(y);
    31     if (x==y)return;
    32     if (sz[x]<sz[y])swap(x,y);
    33     v1[++v1[0]]=y;
    34     f[y]=x;
    35     v2[v1[0]]=make_pair(x,sz[x]);
    36     sz[x]=max(sz[x],sz[y]+1);
    37 }
    38 int main(){
    39     scanf("%d%d",&n,&m);
    40     for(int i=1;i<=m;i++)scanf("%d%d%d",&p[i],&x[i],&y[i]);
    41     for(int i=1;i<=m;i+=K){
    42         int k=min(m,i+K-1);
    43         g2.clear();
    44         for(int j=i;j<=k;j++)
    45             if (p[j]==1){
    46                 check(x[j],y[j]);
    47                 check(x[j]%n+1,y[j]%n+1);
    48             }
    49         for(int j=1;j<=n;j++)f[j]=j;
    50         for(it=g1.begin();it!=g1.end();it++)add((*it).fi,(*it).se);
    51         v1[0]=0;
    52         for(int j=i;j<=k;j++){
    53             x[j]=(x[j]+ans-1)%n+1;
    54             y[j]=(y[j]+ans-1)%n+1;
    55             if (x[j]>y[j])swap(x[j],y[j]);
    56             if (p[j]==1)update(make_pair(x[j],y[j]));
    57             else{
    58                 for(int l=1;l<=v1[0];l++){
    59                     f[v1[l]]=v1[l];
    60                     sz[v2[l].fi]=v2[l].se;
    61                 }
    62                 v1[0]=0;
    63                 for(it=g2.begin();it!=g2.end();it++)add((*it).fi,(*it).se);
    64                 printf("%d",ans=(find(x[j])==find(y[j])));
    65             }
    66         }
    67         for(it=g2.begin();it!=g2.end();it++)g1.insert(*it);
    68     }
    69 }
    View Code
  • 相关阅读:
    FZU Problem 2169 shadow
    tomcat配置虚拟主机
    数据库设计中的14个技巧
    JSP动作--JSP有三种凝视方式
    BoundsChecker使用
    个人收藏的flex特效网址【经典中的极品】
    C++中的explicitkeyword
    Andorid Binder进程间通信---Binder本地对象,实体对象,引用对象,代理对象的引用计数
    深入浅出JMS(一)——JMS简单介绍
    一个有意思的编程练习站点
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11561274.html
Copyright © 2020-2023  润新知