BZOJ 4776([Usaco2017 Open]Modern Art-想法题)

来源:互联网 发布:软件开发考试题 编辑:程序博客网 时间:2024/06/05 20:55

已知一个矩阵,初始全0,你每一次选一个非空子矩阵,涂上一个数。
现在你涂n^2次,其中1~n^2每个数用一次,问哪个数可能是第一次涂的。

我们预先框出每个数字涂的最小子矩阵,然后看看哪些格子是重叠的,显然重叠的地方我们可以排除最后覆盖的数字,剩下的都可以涂。
特判只有一个格子被覆盖的情况。

#include <iostream>#include <cmath>#include <algorithm>#include <cstdio>#include <cstring>#include <string>#include <vector>#include <map>#include <functional>#include <cstdlib>#include <queue>#include <stack>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (100000007)#define pb push_back#define mp make_pair #define fi first#define se second#define vi vector<int> #define pi pair<int,int>#define SI(a) ((a).size())typedef long long ll;typedef unsigned long long ull;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} #define MAXN (1234)#define MN2 (1234567)int f[1234][1234]={},a[MAXN][MAXN];int l[MN2],r[MN2],u[MN2],d[MN2];bool b[MN2]={};int main() {    // freopen("bzoj4776.in","r",stdin);    int n=read();    MEMI(l) MEM(r)    MEMI(u) MEM(d)    int cnt=0;    For(i,n) For(j,n){        int p=read();        if (!p) continue;        a[i][j]=p;        if (!r[p]) cnt++;        l[p]=min(l[p],j);        r[p]=max(r[p],j);        u[p]=min(u[p],i);        d[p]=max(d[p],i);    }    For(i,n*n) if (r[i]) {        f[u[i]][l[i]]++;        f[d[i]+1][r[i]+1]++;        f[u[i]][r[i]+1]--;        f[d[i]+1][l[i]]--;    }    For(i,n) For(j,n) {        f[i][j]+=+f[i][j-1]+f[i-1][j]-f[i-1][j-1];    }    // For(i,n) {    //     For(j,n) cout<<f[i][j]<<' ';cout<<endl;    // }    ll ans=0;    if (n==1) ans=(f[1][1]!=0);     else {        ans=0;        For(i,n) For(j,n) {            if (a[i][j]&&f[i][j]>1)  {                b[a[i][j]]=1;            }        }        For(i,n*n) ans+=!b[i];        if (n>1&&cnt==1) ans--;    }    cout<<ans<<endl;    return 0;}
0 0