直播網(wǎng)站模板網(wǎng)站優(yōu)化推廣外包
https://www.luogu.com.cn/problem/CF1592F1
場上猜了個(gè)結(jié)論,感覺只會(huì)操作1。然后被樣例1hack了。然后就猜如果 ( n , m ) (n,m) (n,m) 為1則翻轉(zhuǎn)4操作,被#14hack了。然后就猜4操作只會(huì)進(jìn)行一次,然后就不知道怎么做下去了。
上面猜的結(jié)論都正確,但是既然猜結(jié)論了,為什么不考慮先證明一波?
考慮2次操作4,代價(jià)為6,只有兩種情況:
而他們都可以用操作1表示出來。
然后考慮怎么做。其實(shí)感覺沒有操作4時(shí),每個(gè)位置是否翻轉(zhuǎn)都可以直接O(1)算出來。但這存在一定難度。
我當(dāng)時(shí)寫的是:
這樣子存在邏輯聯(lián)系,不方便直接表示,所以應(yīng)該考慮把if取得。
怎么去?就多列幾個(gè)表示出來。(相當(dāng)于多一個(gè)媒介)
v i , j = a i , j ? s i ? 1 , j ? s i , j ? 1 ? s i ? 1 , j ? 1 p i , j = v i , j ? s i ? 1 , j ? s i , j ? 1 ? s i ? 1 , j ? 1 v_{i,j}=a_{i,j}\otimes s_{i-1,j}\otimes s_{i,j-1}\otimes s_{i-1,j-1}\\p_{i,j} = v_{i,j}\otimes s_{i-1,j}\otimes s_{i,j-1}\otimes s_{i-1,j-1} vi,j?=ai,j??si?1,j??si,j?1??si?1,j?1?pi,j?=vi,j??si?1,j??si,j?1??si?1,j?1?
然后我們發(fā)現(xiàn)了 s s s 和 a a a 相同。
然后發(fā)現(xiàn)翻轉(zhuǎn)4只會(huì)改變4個(gè)位置。
然后操作4有貢獻(xiàn)只當(dāng)這4個(gè)位置同時(shí)改變。
#include<bits/stdc++.h>
using namespace std;
//#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
//#define M
//#define mo
#define N 510
int n, m, i, j, k, T;
int a[N][N], p[N][N], ans;
char str[N]; signed main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// srand(time(NULL));
// T=read();
// while(T--) {
//
// }auto calc = [&] (int x, int y) -> int {return a[x][y]^a[x+1][y]^a[x][y+1]^a[x+1][y+1]; }; n=read(); m=read(); for(i=1; i<=n; ++i) {scanf("%s", str+1); for(j=1; j<=m; ++j) if(str[j]=='B') a[i][j]=1; }for(i=n; i>=1; --i) for(j=m; j>=1; --j) {p[i][j]=(p[i+1][j]^p[i][j+1]^p[i+1][j+1]); if(a[i][j]^p[i][j]) p[i][j]^=1, ++ans; ans+=calc(i, j); if(i!=n && j!=m && calc(i, j) && calc(i, m) && calc(n, j) && calc(n, m)) k=-1; }printf("%d", ans+k); return 0;
}