周期性问题
第一:
每一列的计算的min是相互独立的,
第二:
每一列的数,要执行操作一或者操作二,达到题目要求
举例4*4矩阵的第一列
情况一:1 5 9 13
情况二:5 9 13 1
情况三:9 13 1 5
情况四:13 1 5 9
用一个tag数组标记那种情况的数量tag[情况某某]++,每一列每种情况算一次n-tag[情况某某]+要进行操作二的次数
数据跑下来大概也就O(4nm),写的时候比较繁琐把
开始题目给的数据n*m<=2e5,这种的只能再跑一个lognm或者一个常数的倍数
#include<bits/stdc++.h>
//typedef long long ll;
//#define ull unsigned long long
//#define int long long
#define F first
#define S second
#define endl "\n"//<<flush
#define lowbit(x) (x&(-x))
#define ferma(a,b) pow(a,b-2)
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const double PI=acos(-1.0);
const int inf=0x3f3f3f3f;
const int MAXN=0x7fffffff;
const long long INF = 0x3f3f3f3f3f3f3f3fLL;
void file()
{
#ifdef ONLINE_JUDGE
#else
freopen("cin.txt","r",stdin);
// freopen("cout.txt","w",stdout);
#endif
}
const int N=2e5+5;
vector<int>G[N];
int tag[N];
signed main()
{
IOS;
//file();
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
G[i].resize(m);
for(int j=0;j<m;j++)
cin>>G[i][j];
}
int ans=0;
for(int i=0;i<m;i++)
{
int temp=inf;
vector<int>vec(n);
for(int j=1;(j-1)*m+i+1<=n*m;j++)
{
tag[(j-1)*m+i+1]=j;
}
for(int j=0;j<n;j++)
{
int num=G[j][i];
if(tag[num])
{
num=((tag[num]-1-j)%n+n)%n;
vec[num]++;
}
}
for(int j=1;(j-1)*m+i+1<=n*m;j++)
{
tag[(j-1)*m+i+1]=0;
}
for(int j=0;j<n;j++)
{
int sum=n-vec[j];
sum+=(n-j)%n;
temp=min(temp,sum);
}
ans+=temp;
}
cout<<ans<<endl;
return 0;
}