zoukankan      html  css  js  c++  java
  • [WC2005]双面棋盘

    description

    洛谷
    给出一个(n imes n)的黑白棋盘。
    (m)次操作,每次将一个格子进行颜色翻转,求每次操作后的黑白四连通块数。

    data range

    [nle 200,mle 10000 ]

    solution

    解决动态维护图连通性的方法有2种:
    一种是通过(LCT)动态维护最大删边时间生成树,另一种是线段树分治。

    所以当然线段树分治更好写不是吗反正不会LCT的做法

    然后稍稍讨论一波就完了

    Code

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define F "a"
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const int N=2e2+10;
    const int K=4e4+10;
    const int mod=998244353;
    const int inf=2147483647;
    const ll INF=1ll<<60;
    const dd eps=1e-7;
    const dd pi=acos(-1);
    il ll read(){
      RG ll data=0,w=1;RG char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
      if(ch=='-')w=-1,ch=getchar();
      while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
      return data*w;
    }
    
    il void file(){
      freopen(F".in","r",stdin);
      freopen(F".out","w",stdout);
    }
    
    int n,m,p[N][N],cnt,c[N][N],v[N][N],b,w;VI a[N][N];bool vis[N][N];
    struct node{int x,y,c;}now;
    vector<node>M[K];
    #define ls (i<<1)
    #define rs (i<<1|1)
    #define mid ((l+r)>>1)
    void modify(int i,int l,int r,int x,int y){
      if(x<=l&&r<=y){M[i].push_back(now);return;}
      if(x<=mid)modify(ls,l,mid,x,y);
      if(mid<y)modify(rs,mid+1,r,x,y);
    }
    
    int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
    struct Mod{int id,u,v;};vector<Mod>cal;
    int nowid,top;
    int fa[K];
    int find(int x){
      if(!fa[x])return x;
      RG int ff=find(fa[x]);
      if(fa[x]!=ff){cal.push_back((Mod){nowid,x,fa[x]});top++;}
      return fa[x]=ff;
    }
    il void merge(int x,int y){
      x=find(x);y=find(y);if(x==y)return;
      cal.push_back((Mod){nowid,x,fa[x]});top++;
      fa[x]=y;
    }
    
    #define pd(i,j) (i<1||i>n||j<1||j>n||!vis[i][j])
    set<int>S;
    il void insert(int x,int y,int col){
      vis[x][y]=1;c[x][y]=col;nowid=p[x][y];
      S.clear();
      for(RG int k=0,xx,yy;k<4;k++){
        xx=x+dx[k];yy=y+dy[k];if(pd(xx,yy))continue;
        if(c[xx][yy]==c[x][y]){
          S.insert(find(p[xx][yy]));
          merge(p[x][y],p[xx][yy]);
        }
      }
      v[x][y]=1-S.size();col?b+=v[x][y]:w+=v[x][y];
    }
    
    il void undo(int x,int y){
      nowid=p[x][y];
      while(top&&cal[top-1].id==nowid)
        fa[cal[top-1].u]=cal[top-1].v,cal.pop_back(),top--;
      c[x][y]?b-=v[x][y]:w-=v[x][y];vis[x][y]=0;
    }
    
    void divide(int i,int l,int r){
      RG int sz=M[i].size();
      for(RG int k=0;k<sz;k++)
        insert(M[i][k].x,M[i][k].y,M[i][k].c);
      if(l==r)printf("%d %d
    ",b,w);
      else{divide(ls,l,mid);divide(rs,mid+1,r);}
      for(RG int k=sz-1;~k;k--)
        undo(M[i][k].x,M[i][k].y);
    }
    
    int main()
    {
      n=read();
      for(RG int i=1;i<=n;i++)
        for(RG int j=1;j<=n;j++)
          {p[i][j]=++cnt;c[i][j]=read()^1;a[i][j].push_back(1);}
      m=read();
      for(RG int i=1,x,y;i<=m;i++){
        x=read();y=read();a[x][y].push_back(i);
      }
      for(RG int i=1;i<=n;i++)
        for(RG int j=1;j<=n;j++)
          a[i][j].push_back(m+1);
      for(RG int i=1;i<=n;i++)
        for(RG int j=1;j<=n;j++)
          for(RG int k=0,sz=a[i][j].size();k<sz-1;k++){
    	c[i][j]^=1;now=(node){i,j,c[i][j]};
    	if(a[i][j][k]!=a[i][j][k+1])
    	  modify(1,1,m,a[i][j][k],a[i][j][k+1]-1);
          }
      divide(1,1,m);
      return 0;
    }
    
    
  • 相关阅读:
    JavaScript基础1
    iOS开发之Quzrtz2D 一:认识Quzrtz2D
    ios开发抽屉效果的封装使用
    ios开发手势处理之手势识别二
    ios开发之手势处理 之手势识别一
    ios开发事件处理之 四:hittest方法的底层实现与应用
    ios开发事件处理之:三 :寻找最合适的view
    ios开发事件处理之 :二:事件的产生与传递
    ios开发事件处理之:一:UIView的拖拽
    ios开发transform属性
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9794469.html
Copyright © 2011-2022 走看看