题目大意:有n个数,每个数只能与自己后面的数配对,相同的配对只算一个,求配对的数量.
我们反过来考虑每个数可以与自己前面多少个数配对,得到答案是不变的.
如果前面的数都不相同的话,那么这个数对答案的贡献是i-1,如果有相同的,那么只要减去相同的就好了.
所以在读入时记录每个数出现的次数最后出现的位置和这个位置前面相同的数,然后就可以一次循环计算答案了.
细节参考代码。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #include <cmath> 7 #define ll long long 8 #define out(a) printf("%lld",a) 9 #define writeln printf(" ") 10 #define max(a,b) a>b?a:b 11 #define min(a,b) a<b?a:b 12 using namespace std; 13 int n,x,mx,cnt; 14 int a[100050],b[100050],c[100050]; 15 ll ans; 16 int read() 17 { 18 int s=0,t=1; char c; 19 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 20 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 21 return s*t; 22 } 23 ll readl() 24 { 25 ll s=0,t=1; char c; 26 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 27 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 28 return s*t; 29 } 30 int main() 31 { 32 n=read(); mx=-2333333; 33 for (int i=1;i<=n;i++){ 34 x=read(); mx=max(mx,x); 35 a[x]++; b[x]=i; 36 if (a[x]>1) cnt++; 37 c[x]=cnt; 38 } 39 for (int i=1;i<=mx;i++) { 40 if (a[i]>0){ 41 if (a[i]==1) ans+=b[i]-c[i]-1; 42 else ans+=b[i]-c[i]; 43 } 44 } 45 out(ans); 46 return 0; 47 }