18 Codeforces Round 853 (Div. 2)C. Serval and Toxel's Arrays(算贡献)

C. Serval and Toxel's Arrays

这种题目做多了应该很容易从贡献的角度去考虑了。

考虑当前版本对答案的贡献,首先这个版本和其他版本取交集至少会包含它本身所以直接先把\(i * n\)给加上去,然后再考虑,前面版本中出现的数当前版本并没有出现的这一部分如何去维护。
下面是怎么去维护这个东西的。

7601323e6898bb7180edfebf84ed2d5.jpg

#include <bits/stdc++.h>

#define int long long
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define fep(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i=(a); i<(b); ++i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>

using namespace std;
const int maxn = 4e5 + 10;
int cnt[maxn],lst[maxn],a[maxn];
int n,m;

void solve() {
    cin>>n>>m;
    rep(i,1,n){
        cin>>a[i];
    }
    rep(i,1,n+m){
        lst[i]=cnt[i]=0;
    }
    int ans=0,sum=0;
    rep(i,1,m){
        int p,q;
        cin>>p>>q;
        int dd=i-lst[a[p]]+cnt[a[p]];
        sum+=dd;
        cnt[a[p]]+=i-lst[a[p]];
        sum-=cnt[q];
        lst[q]=i;
        a[p]=q;
        ans+=sum+i*n;
    }
    cout<<ans<<endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
//	freopen("C:\\Users\\24283\\CLionProjects\\untitled2\\1.in", "r", stdin);
    int _;
    cin >> _;
    while (_--)
        solve();
    return 0;
}
posted @ 2024-03-04 14:57  cxy8  阅读(4)  评论(0编辑  收藏  举报