题意:有一个a序列,a1............an,我们可以求出
,现在将a序列中任意两个数交换位置,变为b序列,现在给出b序列的顺序,给出x 和 y ,计算出对于b序列有几种交换方式,可以变成a序列。
解析: 我们设交换的两个数的下标为 i 和 j ,
则 x = a1 * 1 + a2 * 2 +...+ ai * i + ......+ aj * j +...an * n;
y = a1 * a1 * 1 + a1 * a2 * 2 +...+ ai *ai * i + ......+ aj * aj * j +...+ an *an * n;
对于b序列来说,交换i 和 j:
xb = a1 * 1 + a2 * 2 +...+ aj * i + ......+ ai * j +...an * n;
yb = a1 * a1 * 1 + a1 * a2 * 2 +...+ aj *aj * i + ......+ ai * ai * j +...+ an *an * n;
yb - y = (j - i) * (ai * ai - aj * aj)
xb - x = (j - i) * (ai - aj)
(yb - y) /(xb - x) = ai + aj
通过 (yb - y) /(xb - x) = ai + aj 和 xb - x = (j - i) * (ai - aj) 这两个式子遍历每一数判断是否符合。
代码:
/*************************************************************************
> File Name: 4101.cpp
> Author: ccdxc
> Mail: linyi0430@gmail.com
> Created Time: 2019年05月07日 星期二 11时33分10秒
************************************************************************/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#define ll long long
#define pb push_back
using namespace std;
const int INF = 0x3f3f3f3f;
const int Maxn = 1e5 + 10;
int n , p[Maxn];
ll x , y, xb ,yb , ans ,a[Maxn] ;
int main(){
int T;
cin >> T;
while(T--){
xb = yb = ans = 0;
memset(p , 0 , sizeof(p));
cin >> n >> x >> y;
for(int i = 1;i <= n;i++){
cin >> a[i];
xb += i * a[i];
yb += i * a[i] * a[i];
p[a[i]]++;
}
if((y == yb && x != xb) || (y != yb && x == xb)){
cout <<0 <<"\n";
continue;
}
if(y == yb && x == xb){
for(int i = 1;i <= n;i++)
ans += p[a[i]] - 1;
cout << ans/2 <<endl;
continue;
}
ll tmp1 = yb -y , tmp2 = xb -x;
if(tmp1 % tmp2 !=0){
cout <<0 <<"\n";
continue;
}
ll nu = tmp1 / tmp2;
for(int i = 1;i <= n;i++){
ll ar = nu - a[i];
ll nf = ar - a[i];
if(nf == 0) continue;
if(tmp2 % nf != 0) continue;
ll nt = i + tmp2 / nf;
//cout << nt <<endl;
if(a[nt] == ar && nt >= 1 && nt <= n) ans++;
}
ans /= 2;
cout << ans <<endl;
}