题意:给定长度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;
} 


京公网安备 11010502036488号