设备塔

题目描述

为了封印辉之环,古代塞姆利亚大陆的人民在异空间中建造了一座设备塔。 简单的说,这座设备塔是一个漂浮在异空间中的圆柱体,圆柱体两头的圆是计算核心,而侧面则是 传输信息所用的数据通道,划分成 N ∗ m 个区块。 然而,随着工作的继续进行,他们希望把侧面的一部分区块也改造成其他模块。然而,任何时候都 必须保证存在一条数据通道,能从圆柱体的一端通向另一端。 由于无法使用辉之环掌控下的计算系统,他们寻求你的帮助来解决这个问题。他们将逐个输入想要 改造的区域,而你则执行所有可行的改造并忽略可能导致数据中断的改造。

输入

第一行,包含两个整数 N; M; K,表示侧面的长和宽,以及操作数。 接下来 K 行,每行包含三个整数 xi; yi,表示操作的区块的坐标。 数据保证不会对已经操作成功的区块进行操作。

输出

输出一行,表示有多少个操作可以被执行。

样例输入

3 4 9 2 2 3 2 2 3 3 4 3 1 1 3 2 1 1 1 1 4

样例输出

6

提示

 

对于分值为 30 的子任务 1,保证 N; M ≤ 100; K ≤ 5000。


对于分值为 30 的子任务 2,保证 N; M ≤ 3000; K ≤ 5000。


对于分值为 40 的子任务 3,保证 N; M ≤ 3000; K ≤ 300000。

对障碍的8联通性用并查集维护。
#include<bits/stdc++.h>
#define ha(x,y) (x*(2*m+1)+y)
using namespace std;
int n,m,k,x,y,f[3011*6711],ll,rr,jj,ans,kk,qq;
map<int,int> mp;
bool usd[3011][6011];
int gf(int x){
    return x^f[x]?f[x]=gf(f[x]):x;
}
signed main () {
    scanf("%d%d%d",&n,&m,&k);
    for (int i=ha(n,2*m);i;i--) f[i]=i;
    for (int i=1;i<=k;i++) {
       scanf("%d%d",&x,&y);
//     assert(!usd[x][y]);
       if (usd[x][y]) continue;
       mp.clear();
       kk=0;
       for (int p=x-1;p<=x+1;p++)
        for (int q=y-1;q<=y+1;q++) {
         qq=q;
         if (q==0) {qq=2*m;}
         if (q>2*m) {qq-=2*m;}
          
         if (!usd[p][qq]) continue;
         if (p==x&&qq==y) continue;
          jj=gf(f[ha(p,qq)]);
          mp[jj]=1;
//        ll=min(l[jj],ll); rr=max(r[jj],rr);
        }
       for (int p=x-1;p<=x+1;p++)
        for (int q=y+m-1;q<=y+m+1;q++) {
         qq=q;
         if (q==0) {qq=2*m;}
         if (q>2*m) {qq-=2*m;}
         if (!usd[p][qq]) continue;
         if (p==x&&qq==y+m) continue;
//        cerr<<ha(p,q)<<endl;
          jj=gf(f[ha(p,qq)]);
          if (mp[jj]==1) kk=1;
//        ll=min(l[jj],ll); rr=max(r[jj],rr);
        }
      if (kk) continue;
      ans++; usd[x][y]=1; usd[x][y+m]=1;
      for (int p=x-1;p<=x+1;p++)
        for (int q=y-1;q<=y+1;q++) {
         qq=q;
         if (q==0) {qq=2*m;}
         if (q>2*m) {qq-=2*m;}
         if (!usd[p][qq]) continue;
         if (p==x&&qq==y) continue;
          jj=gf(f[ha(p,qq)]);
          f[jj]=ha(x,y);
        }
       for (int p=x-1;p<=x+1;p++)
        for (int q=y+m-1;q<=y+m+1;q++) {
            qq=q;
         if (q==0) {qq=2*m;}
         if (q>2*m) {qq-=2*m;}
         if (!usd[p][qq]) continue;
         if (p==x&&qq==y+m) continue;
          jj=gf(f[ha(p,qq)]);
          f[jj]=ha(x,y+m);
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2018-08-16 20:20  泪寒之雪  阅读(231)  评论(0编辑  收藏  举报