1. 程式人生 > >【LIbreOJ】#6256. 「CodePlus 2017 12 月賽」可做題1

【LIbreOJ】#6256. 「CodePlus 2017 12 月賽」可做題1

thml 二維 close cst pos opened std hid 都是

【題意】定義一個n階正方形矩陣為“巧妙的”當且僅當:任意選擇其中n個不同行列的數字之和相同。

給定n*m的矩陣,T次詢問以(x,y)為左上角的k階矩陣是否巧妙。n,m<=500,T<=10^5。

【算法】數學

【題解】

可以證明每個矩陣是巧妙的當且僅當其每個2階子矩陣均是巧妙的:

必要性:若該矩陣有一個不巧妙的2階子矩陣,則其他部分選擇相同的情況下(不涉及此兩行列),這兩行列的和不同,所以該矩陣不是巧妙的。

觀察一個巧妙的2階子矩陣

a1 a2

b1 b2

由a1+b2=a2+b1,可得

a2-a1=b2-b1(列間差分相等)

b1-a1=b2-a2(行間差分相等)

充分性:若該矩陣每個2階子矩陣都是巧妙的,則其行差分的列差分均為0(行差分相等和列差分相等)。

重定義每個數字為Mij=ai+bj,表示A(i,j)和A(i-1,j-1)的列差分和行差分分別為ai和bj,這樣的矩陣不論如何選擇排列,和均為Σai+Σbj,1<=i,j<=k,所以該矩陣是巧妙的。

維護二維前綴和即可。

技術分享圖片
#include<cstdio>
#define rep(i,j,k) for(int i=j;i<=k;i++)
int a[600][600],f[600][600],n,m,T,x,y,k;
int main(){
    scanf("%d%d%d",&n,&m,&T);
    rep(i,1,n)rep(j,1,m)scanf("
%d",&a[i][j]); rep(i,1,n-1)rep(j,1,m-1)f[i][j]=f[i][j-1]+(a[i][j]+a[i+1][j+1]!=a[i+1][j]+a[i][j+1]); rep(i,1,n-1)rep(j,1,m-1)f[i][j]+=f[i-1][j]; while(T--){ scanf("%d%d%d",&x,&y,&k); if(f[x+k-2][y+k-2]-f[x-1][y+k-2]-f[x+k-2][y-1]+f[x-1][y-1]>0)puts("N");else
puts("Y"); } }
View Code

【LIbreOJ】#6256. 「CodePlus 2017 12 月賽」可做題1