題解-CF1458C Latin Square


題面

CF1458C Latin Square

\(T\) 組測試數據,每次給一個 \(n\times n\) 的矩陣,每行每列都是個 \(1\to n\) 的排列。有 \(m\) 次操作,如果是 UDLR 就是要把整個矩陣每行/每列往一個方向循環移動一格。如果是 IC,就是把矩陣每行/每列變成原來的逆矩陣。求最后的矩陣。

數據范圍:\(1\le T\le 1000\)\(1\le \sum n\le 1000\)\(1\le \sum m\le 10^5\)\(1\le a_{i,j}\le n\)


題解

剛才有個群友問我 G 菜雞發生腎摸事了,我說怎么回事?給我發了幾張 CF 分數對比圖,我一看!嗷!原來是昨天,我打了一場 CF,爆零了,掉分到 newbie ,又被嘲諷了。

為了方便下標從 \(0\) 開始,即 \(i,j,a_{i,j}\) 的范圍都是 \([0,n)\)

如果只有 UDLR 操作,維護兩位的錯位即可。

這個 IC 操作有很多性質,比如先 IC 和直接 I 形成的矩陣正好是右上-左下翻轉關系。

假如把一個題目中描述的矩陣看成 \(n\times n\)\((i,j,a_{i,j})\) 三元組組成的集合,那么 I 就是讓所有 \((i,j,a_{i,j})\) 變成 \((i,a_{i,j},j)\)C 就是讓所有 \((i,j,a_{i,j})\) 變成 \((a_{i,j},j,i)\)

對於一個三元組 \((i,j,k)\),每次 R 就是讓它變成 \((i,(j+1)\bmod n,k)\)LDU 同理。

所以可以維護對於每個三元組,原來的 \(3\) 維現在變到哪了,以及 \(3\) 維當前各有多少錯位。

由於對於每個三元組情況是一樣的,所以可以每次 \(\Theta(1)\) 維護。

然后最后把矩陣按變化構造即可,總時間復雜度 \(\Theta(n^2+m)\)


代碼

我菜,參考了 tourist 的。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define x first
#define y second
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define sz(a) int((a).size())
#define R(i,n) for(int i(0);i<(n);++i)
#define L(i,n) for(int i((n)-1);i>=0;--i)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;

//Data
const int N=1000;
int n,m,a[N][N][3],b[N][N];
int p[3],o[3],f[3];
string str;

//Main
void Main(){
    cin>>n>>m;
    R(t,3) f[o[t]=t]=0;
    R(i,n)R(j,n){
        cin>>a[i][j][2],--a[i][j][2];
        a[i][j][0]=i,a[i][j][1]=j;
    }
    cin>>str;
    for(char c:str){
        if(c=='R') f[1]++;
        else if(c=='L') f[1]--;
        else if(c=='D') f[0]++;
        else if(c=='U') f[0]--;
        else if(c=='I') swap(o[1],o[2]),swap(f[1],f[2]);
        else if(c=='C') swap(o[0],o[2]),swap(f[0],f[2]);
    }
    R(i,3) (((f[i]%=n)+=n)%=n);
    R(i,n)R(j,n){
        R(t,3) p[t]=(a[i][j][o[t]]+f[t])%n;
        b[p[0]][p[1]]=p[2];
    }
    R(i,n)R(j,n) cout<<b[i][j]+1<<" \n"[n-j==1];
    cout<<'\n';  
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int t; for(cin>>t;t--;Main());
    return 0;
}

祝大家學習愉快!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM