首页 > 其他分享 >AT_abc318_e 题解

AT_abc318_e 题解

时间:2023-09-03 09:02:35浏览次数:69  
标签:cnt abc318 nums int 题解 sum pos leq

AT_abc318_e Sandwiches 题解

洛谷

AtCoder

Description

给定一个长度为 \(n\) 的序列 \(a\),找到满足以下条件的三元组 \((a,b,c)\) 的数量。

  • \(i < j < k\);
  • \(a_{i} = a_{k}\);
  • \(a_{i} \neq a_{j}\)。

数据范围:\(1 \leq n \leq 3 \times 10^{5}\),\(1 \leq a_{i} \leq n\)。

Solution

由于要求 \(i < j < k\),我们可以从左向右枚举 \(k\),考虑对于这个 \(k\) 计算贡献。假设 \(a_{k}\) 在之前出现次数是 \(cnt_{a_{k}}\),出现的位置集合是 \(pos_{a_{k}} = \{pos_{a_{k},1}, \cdots, pos_{a_{k},cnt_{a_{k}}}\}\)。先考虑一种较劣的算法:枚举每个 \(i\),那么 \(j\) 的数量可以很轻松的确定(注意减去中间 \(a_{j}\) 和 \(a_{k}\) 相同的数量)。于是这个 \(k\) 的贡献是:

\[\sum_{i = 1}^{cnt_{a_{k}}} \left ( k - pos_{a_{k},i} - cnt_{a_{k}} + i \right) \]

此时复杂度为 \(\Omicron (n^{2})\)。

考虑拆上面的式子,令其为 \(f(k)\):

\[\begin{aligned} f(k) &= \sum_{i = 1}^{cnt_{a_{k}}} k - \sum_{i = 1}^{cnt_{a_{k}}} pos_{a_{k},i} - \sum_{i = 1}^{cnt_{a_{k}}} cnt_{a_{k}} + \sum_{i = 1}^{cnt_{a_{k}}}i \\ &=cnt_{a_{k}} \cdot k - \sum_{i = 1}^{cnt_{a_{k}}} pos_{a_{k},i} - cnt_{a_{k}}^{2} + \frac{cnt_{a_{k}} \times (cnt_{a_{k}} + 1)}{2} \\ &=cnt_{a_{k}} \cdot k - \sum_{i = 1}^{cnt_{a_{k}}} pos_{a_{k},i} - \frac{cnt_{a_{k}} \times (cnt_{a_{k}} - 1)}{2} \end{aligned} \]

对每个数字为何一个出现位置的前缀和 \(sum = \sum_{i = 1}^{cnt_{a_{k}}} pos_{a_{k},i}\) 就可以 \(\Omicron(1)\) 计算每个 \(k\) 的贡献了,总时间复杂度 \(\Omicron (n)\)。

Codes

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define max_n 510101
void read(int &p)
{
    p = 0;
    int k = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
        {
            k = -1;
        }
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        p = p * 10 + c - '0';
        c = getchar();
    }
    p *= k;
    return;
}
void write_(int x)
{
    if (x < 0)
    {
        putchar('-');

        x = -x;
    }
    if (x > 9)
    {
        write_(x / 10);
    }
    putchar(x % 10 + '0');
}
void writesp(int x)
{
    write_(x);
    putchar(' ');
}
void writeln(int x)
{
    write_(x);
    puts("");
}
int n,ans = 0,nums[max_n],sum[max_n],cnt[max_n];
signed main()
{
    read(n);
    for(int i = 1;i <= n;i++)
    {
        read(nums[i]);
    }
    for(int i = 1;i <= n;i++)
    {
        if(cnt[nums[i]] >= 1)
        {
            ans += cnt[nums[i]] * i - sum[nums[i]] - ((cnt[nums[i]] + 1) * (cnt[nums[i]]) / 2);
        }
        sum[nums[i]] += i;
        cnt[nums[i]]++;
    }
    writeln(ans);
    return 0;
}

标签:cnt,abc318,nums,int,题解,sum,pos,leq
From: https://www.cnblogs.com/yuhang-ren/p/17674562.html

相关文章

  • ABC318
    T1:FullMoon模拟代码实现n,m,p=map(int,input().split())ans=0i=mwhilei<=n:ans+=1i+=pprint(ans)或者答案是\(\lfloor\frac{n+(p-m)}{p}\rfloor\)T2:Overlappingsheets模拟代码实现#include<bits/stdc++.h>#definerep(i,n)f......
  • ABC317题解报告
    我直接从第三题开始讲了。T3把数组\(A\)从大到小排序。然后从前往后把前\(q\)个数加起来,然后判断这\(q\)个数的和与\(d\)的大小关系,如果大了就变成\(d\)。然后有些细节就看代码吧。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintm......
  • 龙芯平台Hadoop集群搭建问题解决
    这几天一直在困扰我pycurl版本和本机的版本不符合他连接又连接的自己自带的版本与系统不相同低级也会报错 https://blog.csdn.net/u010910682/article/details/89496550/?ops_request_misc=&request_id=&biz_id=102&utm_term=pycurl7.45.2%20%E6%90%AD%E9%85%8Dlibcurl%E6%......
  • 【题解】NOIP2021
    咕咕咕的东西总是要补的。A.报数题目描述:报数游戏是一个广为流传的休闲小游戏。参加游戏的每个人要按一定顺序轮流报数,但如果下一个报的数是\(7\)的倍数,或十进制表示中含有数字\(7\),就必须跳过这个数,否则就输掉了游戏。在一个风和日丽的下午,刚刚结束SPC20nn比赛的小r和......
  • 【题解】Luogu[P7706] 「Wdsr-2.7」文文的摄影布置
    Link一道很有意思的线段树题。第一步分析,我们要求最大的\(a_i+a_k-\min{(b_j)}\),事实上我们可以直接省去这个\(\min\)因为要最大化这个东西,选出来的\(b_j\)必然是最小的,所以原题转化为给定\(l,r\)求\(\max{(a_i-b_j+a_k)}\)其中\(i<j<k\)。第二步分析,我们发现这是一......
  • 【题解】Educational Codeforces Round 153(CF1860)
    每次打都想感叹一句,Educational名不虚传。A.NotaSubstring题目描述:有\(t\)组数据,对于每一组数据,你需要判断能否构造一个只由左右括号组成且长度为已经给定字符串的\(2\)倍且已经给定的字符串不是子串的合法字符串。注:合法的字符串是左右括号能完全匹配的字符串。如果能,......
  • 【题解】Luogu-P2482 SDOI2010 猪国杀
    写了\(358\)行,\(11.94\mathrm{KB}\),有这么几个地方写挂了:反猪决斗一定选主猪。游戏结束判定是主猪死亡或全部反猪死亡。决斗可能被反杀,之后不能再出牌。点击查看代码#include<bits/stdc++.h>usingnamespacestd;intn,m;charCh[3];queue<char>Deck;in......
  • CF1863C 题解
    CF1863CMEXRepetition题解Links洛谷CodeforcesDescription给你一个长度为\(n\)的序列\(a\),满足\(\foralli\in[1,n]\),\(0\leqa_{i}\leqn\)且序列中的数互不相同。定义一次操作为:按照\(i\)从\(1\)到\(n\)的顺序,\(a_{i}\gets\operatorname{MEX}(a_{1}......
  • CF1863B 题解
    CF1863BSplitSort题解Links洛谷CodeforcesDescription给定一个\(1\simn\)的排列\(q\),你可以多次进行以下操作:新建一个初始为空的序列\(q\);选择一个整数\(x\)(\(2\leqx\leqn\));按照在\(p\)中出现的顺序将所有小于\(x\)的数添加到序列\(q\)末尾。按照在......
  • P1463 [POI2001] [HAOI2007] 反素数 题解
    P1463[POI2001][HAOI2007]反素数题解可以发现,最大的不超过\(n\)的反素数就是\(1\simn\)中因数最多的数字。证明:设\(x,x\in[1,n]\)为\(1\simn\)中因数最多的数字,则\(x<y\len\)都不会成为答案,因为存在\(x<y\)因数比\(y\)多,同时也不会存在\(y'<x\)......