题
OvO http://codeforces.com/contest/884/problem/E
884e
解
考虑并查集,每个点向上方和左方的点合并,答案即为1的总数减去需要合并的次数
由于只有16MB,考虑动态数组
由于动态数组,则并查集的时候需要一些细节处理,略OVO
而且还卡常数
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm> using namespace std;
namespace fastIO {
#define BUF_SIZE 100000
//fread -> read
bool IOerror = 0;
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline bool read(int &x) {
char ch;
while(blank(ch = nc()));
if(IOerror)
return false;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
return true;
}
inline void read(char *s){
char ch=nc();
for (;blank(ch);ch=nc());
if (IOerror)return;
for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
*s=0;
}
#undef BUF_SIZE
};
using namespace fastIO; const int M=(1<<14)+14;
int ma[M*2],n,m,id;
bool mp[2][M];
int dx[3]={0,0,-1};
int dy[3]={0,-1,0};
int ans;
char s[M/4]; inline int xnum(char spl)
{
if(spl>='A' && spl<='F')
return spl-'A'+10;
else
return spl-'0';
} //inline int getpos(int x,int y)
//{
// return (x-1)*m+y;
//} inline int xgetpos(int x,int y)
{
return (x-id+1-1)*m+y+m;
} //inline void getxy(int pos,int &x,int &y)
//{
// y=(pos-1)%m+1;
// x=(pos-y)/m+1-id+1;
//} inline int fff(int pos)
{
if(ma[pos]==pos) return pos;
return ma[pos]=fff(ma[pos]);
} inline bool check(int x,int y)
{
if(x<=0 || y<=0 || x>n || y>m || mp[x-id+1][y]==0)
return false;
return true;
} void deal(int x,int y)
{
int i,j,x0,y0,pos,pos0,p,p0,xx,xy,xx0,xy0;
pos=xgetpos(x,y);
for(i=1;i<=2;i++)
{
x0=x+dx[i]; y0=y+dy[i];
if(check(x0,y0)==false) continue;
pos0=xgetpos(x0,y0);
p=fff(pos); p0=fff(pos0);
if(p!=p0)
{
ans--;
ma[p0]=p;
}
}
} void xread()
{
int i,j,t,num;
// char chr;
// getchar();
read(s+1);
for(j=1;j<=m/4;j++)
{
// chr=getchar();
// num=xnum(chr);
num=xnum(s[j]);
for(t=4;t>=1;t--)
{
mp[1][(j-1)*4+t]=num&1;
if(num&1) ans++;
// cout<<(num&1)<<' ';
num>>=1;
}
}
// cout<<endl;
} void solve()
{
int i,j,pos;
ans=0;
for(i=1;i<=n;i++)
{
id=i;
for(j=1;j<=m;j++)
mp[0][j]=mp[1][j],ma[j]=ma[m+j]-m;
xread();
for(j=1;j<=m;j++)
if(mp[1][j])
{
pos=xgetpos(i,j);
ma[m+j]=pos;
}
for(j=1;j<=m;j++)
{
if(mp[1][j])
deal(i,j);
}
}
printf("%d\n",ans);
} int main()
{
// freopen("e.in","r",stdin);
int i,j,t,num,tmp;
read(n); read(m);
solve();
return 0;
}