题干:
原题链接
给你n,x,y.再给定移动后的数组b[i]。
x=
∑
i
=
1
n
\sum_{i=1}^{n}
∑i=1ni * a[i], y=
∑
i
=
1
n
\sum_{i=1}^{n}
∑i=1ni * a[i] *a[i]
求有多少种方案能使a[i]数组交换两个数变成b[i]数组
思路:
需要注意的点:因为牵扯的都是整数运算,所以在做除法时要判断是否能除尽
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
ll a[200000];
map<ll,ll>mp;
int main()
{
int n,t;
ll x,y,x1,y1,ans;
scanf("%d",&t);
while(t--)
{
ans=x1=y1=0;
mp.clear();
scanf("%d%lld%lld",&n,&x,&y);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
x1+=i*a[i];
y1+=i*a[i]*a[i];
mp[a[i]]++;
}
if(x-x1==0)
{
if(y-y1!=0)
printf("0\n");
else
{
for(map<ll,ll>::iterator it=mp.begin();it!=mp.end();it++){
ll num=it->second;
ans+=num*(num-1)/2;
}
printf("%lld\n",ans);
}
}
else
{
if(abs(y-y1)%abs(x-x1))
{
printf("0\n");
continue;
}
ll temp=(y-y1)/(x-x1),tx=x-x1,ty=y-y1;
for(int i=1;i<=n;i++){
ll aj=temp-a[i],tt=a[i]-aj;
if(tt==0)
continue;
if(abs(tx)%tt)
continue;
ll j=i+tx/tt;
if(j<=i||j<0||j>n)
continue;
if(aj==a[j]&&(x==(x1+i*a[j]+j*a[i]-i*a[i]-j*a[j]))&&(y==(y1+i*a[j]*a[j]+j*a[i]*a[i]-i*a[i]*a[i]-j*a[j]*a[j])))
ans++;
}
printf("%lld\n",ans);
}
}
return 0;
}