http://codeforces.com/contest/1004/problem/C
题意:
在一行上有n个数字,现在在最左边和最右边各放置一个机器人,左右机器人各有一个数字p和q。现在这两个机器人从起点开始分别向右和向左移动,当它们移动到和他们自己数字相同的格子时就会停止,否则就会一直移动下去知道出界。现在要计算出有多少组不重复的(p,q)可以使得这两个机器人不相遇。
思路:
只要去考虑每个数第一次出现的位置和最后出现的位置即可。这题我用了前缀和的思想,首先从左到右扫描一遍,算出1~i这个区间内有多少个不重复的数。然后从右到左再扫描一遍,算出i~n这个区间内有多少个不重复的数。
最后再扫描一遍即可,对于第i个数(这个数是第一次出现),那么在它右边有多少不重复的数都是可以与之配对的。最后相加即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int maxn = 1e5+5; 6 7 int a[maxn]; 8 int n, first[maxn], last[maxn], fnum[maxn], lnum[maxn]; 9 10 int main() 11 { 12 //freopen("in.txt","r",stdin); 13 scanf("%d",&n); 14 memset(first,-1,sizeof(first)); 15 memset(last,-1,sizeof(last)); 16 fnum[0] = lnum[n+1] = 0; 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%d",&a[i]); 20 fnum[i] = fnum[i-1]; 21 if(first[a[i]]==-1) 22 { 23 first[a[i]] = 1; 24 fnum[i]++; 25 } 26 } 27 for(int i=n;i>=1;i--) 28 { 29 lnum[i] = lnum[i+1]; 30 if(last[a[i]]==-1) 31 { 32 last[a[i]] = 1; 33 lnum[i]++; 34 } 35 } 36 long long ans = 0; 37 for(int i=1;i<=n;i++) 38 { 39 if(fnum[i]-fnum[i-1]==1) 40 { 41 ans += lnum[i+1]; 42 } 43 } 44 printf("%lld\n",ans); 45 return 0; 46 }