C. Weird Sum(数学)

问题 - C - 代码强制 (codeforces.com)

给定我们一个矩阵,上面的数字代表一种颜色,要求算出每种颜色内部两两之间的曼哈顿距离

将每个点的坐标 拆分横坐标和 纵坐标 

任意两个单元格的距离之和 = 任意两个单元格的横坐标差之和 + 这两个单元格的纵坐标差之和。
我们可以分开计算横、纵坐标差之和。

将横坐标升序排列,遍历所有坐标,第 i 个坐标与前面所有坐标差之和为

对于其中一种,排列好 有

x1 ,x2,x3,x4,x5,....

对于前i个点,我们定义si为 第i个点和前面点的距离

s1 = 0  (前面没有点)

s2= x2 -x1 

s3 = x3 -x2 +  x3 - x1 =   x3* 2 - (x1 +x2 )   =x3 *(3-1)  -(x1 + x2 ) 

s4 = x4 -x3 + x4 - x2 + x4 - x1 = x4 * 3 + (x1+x2+x3)  = x4 *( 4-1) - (x1+x2+x3)

si = xi - x(i-1) +..... + xi - x1 = xi * (i-1)  - (x1+x2+...x(i-1))

  

#include <iostream>
#include <vector>
#include <bits/stdc++.h>
#include <unordered_map>
#include <queue>
#include <algorithm>
#define x first
#define y second
#define pb emplace_back
#define fu(i,a,b) for(int i=a;i<=b; ++ i)
#define fd(i,a,b) for(int i=a;i>=b;	-- i)
#define endl '\n'
#define ms(x,y) memset(x,y,sizeof x)
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;


typedef long long LL;
typedef unsigned long long ULL;
typedef vector<vector<LL>> VVL;
typedef vector<vector<int>> VVI;
typedef vector<LL> VL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int,int> PII;
typedef vector<PII> VPII;
typedef pair<PII,int> PIII;
typedef pair<double,double> PDD;
typedef pair<double,int> PDI;
typedef pair<char,int> PCI;
typedef pair<string,int> PSI;
typedef pair<int,string> PIS;
typedef pair<int,char> PIC;
typedef pair<LL,LL> PLL;
typedef __int128 i128;
typedef unsigned long long ULL;
const int N =1e5+ 10,M = N * N ,INF = 0x3f3f3f3f,P = 131;
const double eps = 1e-8,DNF = 1e18;
const int mod = 998244353,base= 20010;
const LL LNF=(LL) INF * INF;



int n,m;
int maxn; // 几种颜色 
VI cnt[2][N];
// 0 -> 放横坐标 1->放纵坐标 
inline void solve()
{
	cin >> n >> m ;
	fu(i,1,n)
	fu(j,1,m)
	{
		int t;cin >> t;
		maxn = max(maxn,t);
		cnt[0][t].push_back(i);
		cnt[1][t].push_back(j);
	}
	fu(i,1,maxn)
	{
		sort(cnt[0][i].begin(),cnt[0][i].end());
		sort(cnt[1][i].begin(),cnt[1][i].end());
	}
	
	LL ans =0 ;
	
	
	fu(i,1,maxn)
	fu(j,0,1)
	{
		LL s=0;int now =0 ;
		for(auto x : cnt[j][i])
		ans +=(LL) x * (now ++ ) - s,s += x;
	}
	cout << ans << endl;		
}

signed main()
{
//  freopen("1.txt","r",stdin);
//	#define int long long 
//	init(N-1);
    // ios
//	cout << fixed<<setprecision(2);
    int t=1;
//    cin>>t;
    int now = 1;
    while(t -- )
    {
//      cout<<"Case "; 
//      cout<<"Case #"; 
//      cout<<"Scenario #"; 
//      cout<< now ++ <<": ";
//      cout<< now ++ <<": \n";
        solve();
    }


    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值