Element Swapping
Time Limit: 1 Second Memory Limit: 65536 KB
DreamGrid has an integer sequence a1,a2,a3,…,ana_1,a_2,a_3,\dots,a_na1,a2,a3,…,an and he likes it very much. Unfortunately, his naughty roommate BaoBao swapped two elements aia_iai and aja_jaj (1≤i<j≤n)(1 \le i < j \le n)(1≤i<j≤n) in the sequence when DreamGrid wasn’t at home. When DreamGrid comes back, he finds with dismay that his precious sequence has been changed into a1,a2,…,ai−1,aj,ai+1,…,aj−1,ai,aj+1,…,ana_1,a_2,\dots,a_{i-1},a_j,a_{i+1},\dots,a_{j-1},a_i,a_{j+1},\dots,a_na1,a2,…,ai−1,aj,ai+1,…,aj−1,ai,aj+1,…,an
What’s worse is that DreamGrid cannot remember his precious sequence. What he only remembers are the two values
x=∑k=1nkakandy=∑k=1nkak2\ x = \sum_{k=1}^nka_k \qquad \text{and} \qquad y = \sum_{k=1}^nka_k^2 x=∑k=1nkakandy=∑k=1nkak2
Given the sequence after swapping and the two values DreamGrid remembers, please help DreamGrid count the number of possible element pairs (ai,aj)(a_i,a_j)(ai,aj) BaoBao swaps.
Note that as DreamGrid is poor at memorizing numbers, the value of or might not match the sequence, and no possible element pair can be found in this situation.
Two element pairs (ai,aj)(1≤i<j≤n)(a_i,a_j)(1 \le i < j \le n)(ai,aj)(1≤i<j≤n) and (ap,aq)(1≤p<q≤n)(a_p,a_q)(1 \le p < q \le n)(ap,aq)(1≤p<q≤n) are considered different if i≠pi =\not pi≠p or j≠qj =\not qj≠q.
Input
There are multiple test cases. The first line of the input contains an integer TTT, indicating the number of test cases. For each test case:
The first line contains three integers nnn,xxx and yyy (2≤n≤105,1≤x,y≤1018)(2 \le n \le 10^5,1 \le x,y \le 10^{18})(2≤n≤105,1≤x,y≤1018), indicating the length of the sequence and the two values DreamGrid remembers.
The second line contains nnn integers b1,b2,…,bn(1≤bi≤105)b_1,b_2,\dots,b_n(1 \le b_i \le 10^5)b1,b2,…,bn(1≤bi≤105), indicating the sequence after swapping. It’s guaranteed that ∑k=1nkbk≤1018\sum_{k=1}^nkb_k \le 10^{18}∑k=1nkbk≤1018 and ∑k=1nkbk2≤1018\sum_{k=1}^nkb_k^2 \le 10^{18}∑k=1nkbk2≤1018.
It’s guaranteed that the sum of of all test cases will not exceed 2×1062 \times 10^62×106.
Output
For each test case output one line containing one integer, indicating the number of possible element pairs BaoBao swaps.
Sample Input
2
6 61 237
1 1 4 5 1 4
3 20190429 92409102
1 2 3
Sample Output
2
0
Hint
For the first sample test case, it’s possible that BaoBao swaps the 2nd and the 3rd element, or the 5th and the 6th element.
题目大意:
第一行输入一个整数ttt,代表有ttt组测试样例,对于每组测试样例,先输入三个整数n,x1,y1n,x_1,y_1n,x1,y1,下一行再输入nnn个整数的数组a1,a2,…,ana_1,a_2,\dots,a_na1,a2,…,an(1≤ai≤105)(1 \le a_i \le 10^5)(1≤ai≤105),现在我们能交换数组中的任意两个元素aia_iai和aja_jaj (1≤i<j≤n)(1 \le i < j \le n)(1≤i<j≤n),使得改变后的数组求得的x,yx,yx,y变为x1,y1x1,y1x1,y1,问有多少种交换方案。
解题思路:
通过题意我们可以知道,此题相当于我们可以根据公式x=∑k=1nkakx=\sum_{k=1}^nka_kx=∑k=1nkak 和 公式y=∑k=1nkak2y=\sum_{k=1}^nka_k^2y=∑k=1nkak2求出当前数组的xxx和yyy,我们可以将其记作x2,y2x_2,y_2x2,y2,交换数组中的两个元素后的x,yx,yx,y为x1,y2x_1,y_2x1,y2,因为我们仅交换了数组中的两个元素,所以根据x,yx,yx,y的公式,我们可以知道x1,x2x_1,x_2x1,x2的区别在于x2x2x2中ai,aja_i,a_jai,aj两项为iai+jajia_i +ja_jiai+jaj,而x1x1x1也就是交换后ai,aja_i,a_jai,aj两项为jai+iajja_i +ia_jjai+iaj,其他项完全相同,所以可以得到x2−x1=(i−j)(ai−aj)x2-x1=(i-j)(a_i-a_j)x2−x1=(i−j)(ai−aj),同理y2−y1=(i−j)(ai2−aj2)y2-y1=(i-j)(a_i^2-a_j^2)y2−y1=(i−j)(ai2−aj2)即y2−y1=(i−j)(ai−aj)(ai+aj)y_2-y_1=(i-j)(a_i-a_j)(a_i+a_j)y2−y1=(i−j)(ai−aj)(ai+aj)。
因此可以先假设x=x2−x1,t=y2−y1x=x_2-x_1,t=y_2-y_1x=x2−x1,t=y2−y1,如果x==0&&y==0x==0\&\&y==0x==0&&y==0的话,那么则证明ai==aja_i==a_jai==aj,则方案数则为数组中选取任意两个相同项的方案数,例如假设aaa在数组中出现了kkk次,则ans+=Ck2ans+=C_k^2ans+=Ck2。
若x≠0&&y≠0x=\not 0 \&\& y=\not 0x≠0&&y≠0,通过x=(i−j)(ai−aj)x=(i-j)(a_i-a_j)x=(i−j)(ai−aj)和y=(i−1)(ai−aj)(ai+aj)y=(i-1)(a_i-a_j)(a_i+a_j)y=(i−1)(ai−aj)(ai+aj),可知y/x=ai+ajy/x=a_i+a_jy/x=ai+aj,这是就可以判断一下若y%x==0y\%x==0y%x==0则存在,否则ans=0ans=0ans=0,因此可以得到ai+aja_i+a_jai+aj的值,此时就可以通过遍历数组a[]a[]a[],求出其对应的a[j]a[j]a[j],通过遍历可以确定i,a[i],a[j]i,a[i],a[j]i,a[i],a[j]的值,然后根据x=(i−j)(ai−aj)x=(i-j)(a_i-a_j)x=(i−j)(ai−aj),可以求出jjj,这时只需判断数组中的第jjj项是否为a[j]a[j]a[j],若是则方案数加一。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <utility>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
//priority_queue<int,vector<int> ,greater<int> >q;
const int maxn = (int)1e5 + 5;
const ll mod = 1e9+7;
ll arr[100100];
ll num[100100];
set<ll> s;
int main()
{#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);#endif//freopen("out.txt", "w", stdout);ios::sync_with_stdio(0),cin.tie(0);int t;scanf("%d",&t);while(t--) {int n;ll x1,x2=0,y1,y2=0;scanf("%d %lld %lld",&n,&x1,&y1);s.clear();memset(num,0,sizeof num);rep(i,1,n) {scanf("%lld",&arr[i]);x2+=(ll)i*arr[i];y2+=(ll)i*arr[i]*arr[i];s.insert(arr[i]);num[arr[i]]++;}ll x=x2-x1,y=y2-y1;ll ans=0;if(x==0&&y==0) {for(auto it=s.begin();it!=s.end();it++) {if(num[*it]>1) {ans+=(num[*it]*(num[*it]-1))/2LL;}}}else if(x!=0&&y!=0) {if(y%x==0) {ll t=y/x;for(int i=1;i<=n;i++) {if(t-arr[i]>0&&t-arr[i]<=100000&&num[t-arr[i]]>0) {ll nape=arr[i]-(t-arr[i]);if(nape!=0&&x%nape==0) {int k=i-x/nape;if(k>i&&k<=n&&arr[k]==t-arr[i]) ans++;}}}}else ans=0;}else ans=0;printf("%lld\n",ans);}return 0;
}