版权声明:本文为博主原创文章,顺手点个赞叭~有问题欢迎指出(*╹▽╹*) https://blog.csdn.net/qq_41117236/article/details/89640765
【题面】
【题解】
题意:给定一个长度为n的有两个元素被交换了位置的序列和x,y,x和y的含义如下图,输出可能被交换的元素对(i,j)的数目。
思路:一看就是数学题啊..
令原x,y为x1,y1,改变后x,y为x2,y2,交换元素为ai,aj(j>i),则得到以下公式
由公式可得,当x2-x1=0时,说明ai=aj,此时若y2-y1=0,则输出所有相等元素对数;若y2-y1≠0 ,则不合法。当x2-x1≠0时,由公式求出理论位置j和aj并判断是否相对应,若相对应则计数,最后输出答案即可。
【代码】
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
ll a[maxn];
map <ll,ll> mp;
map <ll,ll> ::iterator it;
int main()
{
int t; scanf("%d",&t);
while(t--){
mp.clear();
ll x1,y1,x2=0,y2=0; int n;
scanf("%d%lld%lld",&n,&x1,&y1);
for(ll i=1;i<=n;i++){
scanf("%lld",&a[i]);
mp[a[i]]++;
x2+=a[i]*i;
y2+=a[i]*a[i]*i;
}
ll dx=x2-x1,dy=y2-y1;
ll ans=0;
if(dx==0&&dy==0){
for(it=mp.begin();it!=mp.end();it++)
ans+=((it->second)-1)*(it->second)/2;
}
else if(dx&&dy%dx==0){
ll sum=dy/dx;
for(ll i=1;i<=n;i++){
ll aj=sum-a[i];
if(aj-a[i]==0) continue;
ll j=dx/(aj-a[i])+i;
if(j>i&&j<=n&&aj==a[j]) ans++;
}
}
printf("%lld\n",ans);
}
}