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=1n?kak?andy=∑k=1n?kak2?
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=1n?kbk?≤1018 and ∑k=1nkbk2≤1018\sum_{k=1}^nkb_k^2 \le 10^{18}∑k=1n?kbk2?≤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=1n?kak? 和 公式y=∑k=1nkak2y=\sum_{k=1}^nka_k^2y=∑k=1n?kak2?求出當前數組的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;
}