NC25118. 291045 / 克洛涅的照片
描述
输入描述
第一行包含四个整数 n, m, k, q 。意义见题面描述。
接下去 k 行,每行包含两个正整数 ,表示被模糊的格子坐标。保证 k 个坐标两两不同。
再接下去 q 行,每行两个整数 ,表示一次修改。当 op=0 时,取反第 x 行;当 op=1 时,取反第 x 列。
输出描述
输出共包含 q+1 行。每行一个整数。第一行表示未进行修改时的答案;之后 q 行每行对应一次操作后的答案。
示例1
输入:
3 3 4 2 1 3 2 1 2 2 3 3 0 1 0 3
输出:
2 3 2
说明:
初始时,照片状态为 ,此时取反第 2 行再取反第 3 列即可。答案为 2 。C++14(g++5.4) 解法, 执行用时: 74ms, 内存消耗: 9548K, 提交时间: 2019-05-23 20:00:34
#include<cstdio> #include<algorithm> using namespace std; int gi(){ int x=0,w=1;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')w=0,ch=getchar(); while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return w?x:-x; } const int N=1e6+5; int n,m,k,q,a[N],b[N],A,B,rev; int main(){ n=gi();m=gi();k=gi();q=gi(); for(int i=1;i<=k;++i){ int x=gi(),y=gi(); if(x==1)b[y]=1,++B; if(y==1)a[x]=1; } for(int i=1;i<=n;++i)A+=a[i]^a[1]; printf("%d\n",min(A+B,n+m-A-B)); while(q--){ int x=gi(),y=gi(); if(x&1)B-=b[y]^rev,b[y]^=1,B+=b[y]^rev; else if(y==1)a[1]^=1,B=m-B,rev^=1,A=n-1-A; else A-=a[y]^a[1],a[y]^=1,A+=a[y]^a[1]; printf("%d\n",min(A+B,n+m-A-B)); } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 112ms, 内存消耗: 9836K, 提交时间: 2019-05-10 22:19:06
#include<bits/stdc++.h> #define rep(a,b,c) for(int a=b;a<=c;a++) typedef long long ll; using namespace std; // lyt int a,b,c,N,M,K,Q,ans,qx[1000007],qy[1000007]; int main () { scanf("%d%d%d%d",&N,&M,&K,&Q); rep(i,1,K){ scanf("%d%d",&a,&b); if (b==1) qx[a]^=1; if (a==1){ qy[b]^=1; if (b==1) rep(j,1,N) qx[j]^=1; } } rep(i,1,N) if (qx[i]) ans++; rep(j,1,M) if (qy[j]) ans++; c=1; if (N+M-ans<ans) ans=N+M-ans,c=-c; printf("%d\n",ans); rep(i,1,Q){ scanf("%d%d",&a,&b); if (a==0){ if (!qx[b]) ans+=c,qx[b]=1; else ans-=c,qx[b]=0; } else{ if (!qy[b]) ans+=c,qy[b]=1; else ans-=c,qy[b]=0; } if (N+M-ans<ans) ans=N+M-ans,c=-c; printf("%d\n",ans); } return 0; }