题目大意:
数组a通过交换一对数字,得到了b数组,给出和b数组,问有多少对l,r(l<=r)能满足条件
思路:
这是一道推公式的题
- a[i] + a[j] = (Y2-Y1) / (X2-X1)
- ( j - i ) * ( a[j] - a[i] ) = ( X2 - X1 )
- 第一个式子右边是一个定值,那么就可以枚举 i (1–n) 通过 a [i] 计算出 a[j] ,再通过第二个式子计算出 a[j] 从而得到 j ,如果a[j]==上一步计算出a[j] ,那么sum++;
- 三种情况
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#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))
const int maxn = (int)1e5 + 5;
const ll mod = 1e9+7;
ll arr[100100];
ll num[100100];
set<ll> s;
int main()
{
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) {
set<ll>::iterator it;
for(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;
}