其他分享
首页 > 其他分享> > C.Weird Sum(点贡献)

C.Weird Sum(点贡献)

作者:互联网

C.Weird Sum

Tag

点贡献

题目来源

Codeforces Round #775 (Div. 2, based on Moscow Open Olympiad in Informatics)

题目大意

给定一个\(n \times m\)的表格,表格的元素代表着颜色的种类,求问所有相同种类的颜色的距离和,定义两个表格之间的距离为它们的横坐标和纵坐标的差之和,例如(1,2)到(3,3)的距离为3

解题思路

\[\sum_{i}\sum_{j}{\left|x_i-x_j\right|} + \sum_{i}\sum_{j}{\left|y_i-y_j\right|} \]

\[\sum_{i}\sum_{j}{\left|x_i-x_j\right|} = \sum_{i=2}^n{(x_i-x_{i-1})\times (i-1)\times(n-i+1)} \]

n表示1的个数

AC代码

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0)
#define LL long long
#define maxn (int)(1e6 + 10)
#define FFF freopen("out", "w", stdout);

int n , m;
vector<int> mp[maxn];
vector<int> rr[maxn], cc[maxn];

int main ()
{
    IOS;
    cin >> n >> m ;
    for ( int i = 1 ; i <= n ; i++ ) 
    {
        mp[i].push_back(0);
        for ( int j = 1 ; j <= m ; j++ )
        {
            int x ; cin >> x;
            rr[x].push_back(i);
            mp[i].push_back(x);
        }
    }
    for ( int j = 1 ; j <= m ; j++ )
    {
        for ( int i = 1 ; i <= n ; i++ )
        {
            int x = mp[i][j];
            cc[x].push_back(j);
        }
    }
    LL ans = 0;
    for ( int i = 1 ; i <= 100000 ; i++ )
    {
        if ( rr[i].size() > 1 )
        {
            for ( int j = 1 ; j < rr[i].size() ; j++ )
            {
                LL len = rr[i][j] - rr[i][j-1];
                ans += 1ll * (rr[i].size() - j ) * len * j;
            }
        }
        if ( cc[i].size() > 1 )
        {
            for ( int j = 1 ; j < cc[i].size() ; j++ )
            {
                LL len = cc[i][j] - cc[i][j-1];
                ans += 1ll * (cc[i].size() - j) * len * j;
            }
        }
    }
    cout << ans << endl;

}

标签:rr,int,sum,贡献,cc,Weird,Sum,size
来源: https://www.cnblogs.com/I-wanna-be-the-kid/p/15974954.html