HDU 6128 Inverse of sum(数学)
来源:互联网 发布:太原市九鼎软件 编辑:程序博客网 时间:2024/04/29 06:13
HDU 6128 (数学计算) 2017ACM暑期多校联合训练 - Team 7 1009 Inverse of sum
题目链接
Problem Description
There are n nonnegative integers a1…n which are less than p. HazelFan wants to know how many pairs i,j(1≤i<j≤n) are there, satisfying 1ai+aj≡1ai+1aj when we calculate module p, which means the inverse element of their sum equals the sum of their inverse elements. Notice that zero element has no inverse element.
Input
The first line contains a positive integer T(1≤T≤5), denoting the number of test cases.
For each test case:
The first line contains two positive integers n,p(1≤n≤105,2≤p≤1018), and it is guaranteed that p is a prime number.
The second line contains n nonnegative integers a1…n(0≤a<p).
Output
For each test case:
A single line contains a nonnegative integer, denoting the answer.
Sample Input
2
5 7
1 2 3 4 5
6 7
1 2 3 4 5 6
Sample Output
4
6
题意:
给定一个数组a,找出数组a里面所有的满足当(1≤i&j≤n)是,1/(ai+aj)≡1/ai+1/aj的关系有多少对。
分析:
来自学姐博客链接
如果暴力遍历整个a数组的话,因为i,j的位置都需要确定,时间复杂度相当于n^2,肯定会超时,所以想办法将上面的式子进行变形,使之变为在O(n)的时间之内可以确定出来结果。
将式子通分后化简可得(ai^2+aj^2+ai*aj)%p=0 。
然后等式两边同时乘上(ai-aj),化简可得(ai^3-aj^3)%p=0。现在的问题就转换为求满足这个关系的对数。
但是直接计算满足这个等式的pair的对数就可以了吗?不是。我们还要考虑到a[i]=a[j]的时候。
当a[i]=a[j]时,(ai^2+aj^2+aiaj)%p=0 可以转换为
(a[i]a[i]+a[i]a[i]+a[i]a[i])%p=0%p
(因为p是素数)是不满足条件的,但是我们直接计算上面那个式子会把满足这个关系的式子也算进去,所以我们需要把满足a[i]=a[j]即 3a[i]a[j]>0的这些对数减掉。 这样求出来的才是最终的结果。
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<map>using namespace std;typedef long long ll;const int maxx=1e5+7;int t,n;ll p,a[maxx];map<ll,int>hsh;map<ll,int>cnt;ll gaga(ll a, ll b)///求b个a相加的和{ ll sum=0; while(b) { if(b&1) sum=(sum+a)%p; b>>=1,a=(a+a)%p; } return sum;}int main(){ scanf("%d",&t); while(t--) { scanf("%d%lld",&n,&p); hsh.clear(),cnt.clear(); ll sum=0; for(int i=1;i<=n;i++) { scanf("%lld",a+i); if(!a[i]) continue; if(gaga(gaga(a[i],a[i]),3)) ///判断3*a[i]*a[i]不等于零? sum-=cnt[a[i]];///如果3*a[i]*a[i]不等于零,就减去a[i]与前面能组合的个数,即cnt[a[i]]个 temp=gaga(temp,a[i]); ll temp=gaga(gaga(a[i],a[i]),a[i]);///求a[i]*a[i]*a[i] sum+=hsh[temp]++;///当前求出的这个tp值可以于之前的所有的相匹配,匹配过后个数再加,下次匹配时的方案数就是这次加过之后的 cnt[a[i]]++; } printf("%lld\n",sum); } return 0;}
- HDU 6128 Inverse of sum(数学)
- HDU 6128 Inverse of sum(二次剩余)
- hdu-6128 Inverse of sum 推公式
- HDU 6128 Inverse of sum(推公式)
- HDU-6128 Inverse of sum(二次剩余/公式)
- HDU 6128 Inverse of sum(取模+map处理)
- HDU 6128 Inverse of sum(数论)——2017 Multi-University Training Contest
- HDU 6128 Inverse of sum (数论, 2017 Multi-Univ Training Contest 7)
- Inverse of sum
- hdu6128 Inverse of sum 2017多校第七场1009 数学
- HDU 5776 sum(数学)
- HDU 5053 the Sum of Cube(数学求立方和)
- hdu 3113 Sum of Cubes 数学 枚举 剪枝
- 633. Sum of Square Numbers (数学)
- HDU 1977 Consecutive sum II(数学)
- HDU 4675 GCD of Sequence(数学)
- HDU 5018 Revenge of Fibonacci(数学)
- HDU 5019 Revenge of GCD(数学)
- Qt信号槽使用注意事项
- 203。Remove Linked List Elements
- JavaScript冒泡排序(冒泡排序最优版)包括如果原数组已经排好顺序,不需要在比较,直接终止循环!
- Linux 屏幕亮度调节
- Console类的输入与输出学习
- HDU 6128 Inverse of sum(数学)
- 什么是多态,多态的概念,多态的体现,多态的应用
- spring aop实现打印方法执行时间
- 购物车
- 智能小车十六《openwrt虚拟机连接网络》
- bootstrap3-dialog-master模态框
- selenium2.0关于python的常用函数
- PRU-ICSS EtherCAT slave package
- RxJava2.0中just操作符用法和源码分析(二)