题意:给定长度n的数组a[],问所有的连续子数组中有多少对相同的数。这不就是整个a[]有多少对相同的数的变种题吗是不是叫一维数点来着?~~
一对相同的数ai,aj,它们一共在i*(n-j+1)个子数组内出现过。根据这个直接算贡献。
用mp[a[i]]维护a[i]在1-(i-1)的出现过的坐标和。这样每次找到a[i],就方便O(log)查询,O(1)计算a[i]与之前所有与a[i]相同的数组成的对的贡献:(本质是提取公因数)
ans+=mp[a[i]]*n-i+1,mp[a[i]]+=i.
复杂度O(Σ nlogn)
#include<bits/stdc++.h> #define ll long long using namespace std; map<ll,ll> mp; ll a[100010]; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); ll t,n,ans; cin>>t; while(t--) { cin>>n; ans=0; for(int i=1;i<=n;++i) { cin>>a[i]; ans+=mp[a[i]]*(n-i+1); mp[a[i]]+=i; } cout<<ans<<endl; for(int i=1;i<=n;++i) { mp[a[i]]=0; } } //getchar();getchar(); return 0; }