Description
ly有 n 个数,现在她想知道这 n 个数中取出一对数 (x,y) 满足 x%3 <= y%3 的方案数是多少。其中,在这个数列中,x的位置要比y前面。
Input
输入两行,第一行包含一个正整数 n ,表示数的数量。
第二行包含 n 个正整数,ai 表示数列中的第 i 个数。
题目保证 1 <= n <= 10^5, 1 <= ai <=10^9
Output
输出一行,为一个整数,为所求的答案。
Sample Input
4
1 3 4 2
Sample Output
5
解析:1.要求x%3 <= y%3,因此我们可以注意到,我们可以将整个序列全部都%3,然后发现只有0,1,2三种情况😱!
2.因为x位置要在y前面,所以题目其实让我们求每个a[ i ]后面的序列有多少大于a[ i ]的数量总和,因此我们得从后面开始遍历,同时记录更新0,1,2现有的数量a,b,c。如果a[ i]=0,那么a[ i ]对答案的贡献就是a+b+c,然后a++。如果a[i]=1, 贡献就是b+c,然后b++,a[i]=2,贡献就是c,c++;
3.方案数最大情况超int了,我们使用long long。
#include <stdio.h>
int k[100005];
int main()
{
int n,i,l,a=0,b=0,c=0; //abc分别记录现有出现的0,1,2数量
long long s=0; //记录方案数
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%d",&l),k[i]=l%3;//全部模3存入
for(i=n-1;i>=0;i--){ //从后面开始
if(k[i]==0) s+=a+b+c,a++;
else if(k[i]==1) s+=b+c,b++;
else if(k[i]==2) s+=c,c++;
}
printf("%lld\n",s);
return 0;
}