C - Sequence Pair Weight(组合数学)

Posted zjj0624

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C - Sequence Pair Weight(组合数学)相关的知识,希望对你有一定的参考价值。

题意
给你一个数组,让你求每一个子串里面一共有多少的pair,
pair就是 i ! = j i!=j i!=j a [ i ] = = a [ j ] a[i]==a[j] a[i]==a[j]的的数量。
思路
例子
4
1 1 2 1
[1,1] 里面有1个。
[1,2] 里面有0个。
[2,1] 里面有0个。
[1,1,2] 里面有1个。
[1,2,1] 里面有1个。
[1,1,2,1] 里面有3个。
数据范围是1e5,我们要想一个o(nlogn)的算法或者o(n)的算法。
我们可以算一下前两个1,1都出现在那些子串里面。
[1,1], [1,1,2],[1,1,2,1].
我们可以发现规律,每两个点产生的贡献就是 ( i ) ∗ ( n − j + 1 ) 。 (i)* (n-j+1)。 (i)(nj+1)
前两个1的贡献就是 1 ∗ ( n − 2 + 1 ) 1 * (n-2+1) 1(n2+1)
当我们算第二个和第三个1的贡献的时候,第一个1和第三个1也会产生贡献。
第二个1和第三个1产生的贡献就是 2 ∗ ( n − 4 + 1 ) 2*(n-4+1) 2(n4+1)
第一个1和第三个1产生的贡献就是 1 ∗ ( n − 4 ) + 1 1*(n-4)+1 1(n4)+1
所以第三个1和前两个的1产生的贡献就是 ( 1 + 2 ) ∗ ( n − 4 + 1 ) (1+2)*(n-4+1) 1+2n4+1
所以说第三个1和前两个1产生的贡献就是前两个1的下边的和,所以我们可以用一个map来存下来。
这样就可以o(n)的求出所有的贡献了。
代码

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
ll a[100010];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        map<int,ll>mp;
        int n;
        cin>>n;
        ll ans=0;
        for(int i=1 ; i<=n ; i++)
        {
            int x;
            cin>>x;
            ans+=mp[x]*(n-i+1);
            mp[x]+=i;
        }
        cout<<ans<<endl;
    }
    return 0;
}

以上是关于C - Sequence Pair Weight(组合数学)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #721 (Div. 2)- C.Sequence Pair Weight - 双重前缀和累加

C. Sequence Pair Weight——Codeforces Round #721 (Div. 2)

Codeforces Round #721 (Div. 2) C. Sequence Pair Weight(计算贡献/STL)

Sequence Pair Weight

C. Sequence Pair Weight(组合计数)

Codeforces Round #721 (Div. 2) C. Sequence Pair Weight