Gym

来源:互联网 发布:淘宝网吧二手电脑 编辑:程序博客网 时间:2024/06/05 02:10

http://codeforces.com/gym/101550/attachments
如图所示。
每次染色,然后问你联通块数有多少。
直接看图就行。
思路:比赛的时候想出来了,但是时间不够了,写了一个开头,本来是写对了,但是我看错了坐标,感觉很麻烦就没写。。
离线处理,然后先记录最后一个的联通块数(有一个空块就+1,联通一次就-1.这样就能得到联通块数)然后依次减去以前的操作,再次统计。
错的地方:① 我把他们都变成了一维表,因为我不太会二维并查集并且我感觉那样很慢。。但是有一个地方要注意,下面会画图说。
② 这道题的坐标很魔性。。
这里写图片描述
绿色这一排,不可以-1,红色这一排不可以+1,(摔啊,直接用一个二维数组存,然后并查的时候用一维不就好了么。用二维的方向坐标就没这么多事了qwq)

#include <bits/stdc++.h>using namespace std;/*  暴力维护。离线处理。*/const int maxn=1e6+5000;struct Node{  int x,y;  int x2,y2;  Node(int a,int b,int c,int d){      x=a;      y=b;      x2=c;      y2=d;  }};stack<Node>q;stack<int>pp;int num[maxn];int m,n,q1;int a,b,c,d;int fa[maxn];int cost[4];int  find2(int x){     if(x==fa[x]) return x;     return fa[x]=find2(fa[x]);}int ans;bool merge2(int x,int y){    if(x<0||y<0||x>=m*n||y>=m*n) return false;    int a=find2(x);    int b=find2(y);    if(a==b) return false;    fa[a]=b;    //cout<<"change"<<a<<" "<<b<<"????????"<<x<<" "<<y<<endl;    ans--;    return true;}int main(){    scanf("%d%d%d",&m,&n,&q1);     cost[0]=1;     cost[1]=-1;     cost[2]=n;     cost[3]=-n;     for(int i=0;i<m*n;i++){        fa[i]=i;     }     for(int i=0;i<q1;i++){          scanf("%d%d%d%d",&a,&b,&c,&d);          a--,b--,c--,d--;          swap(a,b);swap(c,d);          if(a==c){             if(b>d) swap(b,d);             for(int j=b;j<=d;j++)                 num[j*n+a]++;          }          else if(b==d){              if(a>c) swap(a,c);              for(int j=a;j<=c;j++){                 num[b*n+j]++;              }          }           q.push(Node(a,b,c,d));     }     ans=0;      for(int i=0;i<m*n;i++){           if(!num[i]){                //cout<<num[i]<<" "<<i<<endl;                ans++;          for(int j=0;j<4;j++){              if(j==0&&(i%n==(n-1))) continue;              if(j==1&&i%n==0) continue;              if(!num[i]&&!num[i+cost[j]])                 { merge2(i,i+cost[j]);                 }          }          }      }      //cout<<ans<<"!!"<<endl;      pp.push(ans);     while(!q.empty()){          Node u=q.top();          q.pop();          a=u.x;          b=u.y;          c=u.x2;          d=u.y2;          //cout<<a<<"????"<<b<<c<<d<<endl;           if(a==c){             if(b>d) swap(b,d);             for(int j=b;j<=d;j++){                 num[j*n+a]--;                 int t=j*n+a;                 if(!num[t]) {ans++;                 //cout<<t<<"!!!"<<endl;              for(int j=0;j<4;j++){                      if(j==0&&t%(n)==(n-1)) continue;              if(j==1&&t%n==0) continue;                 if(!num[t]&&!num[t+cost[j]]){                     merge2(t,t+cost[j]);                 }              }              }              }          }          else if(b==d){              if(a>c) swap(a,c);              for(int j=a;j<=c;j++){                 num[b*n+j]--;                 int tt=b*n+j;                 if(!num[tt]) ans++;              for(int j=0;j<4;j++){                      if(j==0&&tt%(n)==(n-1)) continue;              if(j==1&&tt%n==0) continue;                 if(!num[tt]&&!num[tt+cost[j]]){                     merge2(tt,tt+cost[j]);                 }              }              }          }      pp.push(ans);     }     pp.pop();     while(!pp.empty()){           printf("%d\n",pp.top());           pp.pop();     }    return 0;}
原创粉丝点击