签到八题之一
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6003
题目大意:懒~上边链接,题面通俗易懂。
思路:水水题。假设这样的数存在的话,我们分别设值为a,b;位置为ax,bx。
设题目给的两个式子,设
然后X,Y如题目所给,代表我们交换以后的目标公式值。我们可得关系式
化简得:
式子1
式子2
我们观察两个等式的左半部分,显然有
即
这样便可确定b的值唯一,且能求出b的值。
再把所有参数代入 中,可得
代表bx也为定值,且可求出来。
这样一来,我们只需要判断bx位置的值是否为b即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100005];
unordered_map<ll,ll >mp;
int main()
{
int n,t,m,i,j;
ll x,y,ans,num,sum1,sum2,b,k;
scanf("%d",&t);
while(t--)
{
ans=sum1=sum2=0;
scanf("%d%lld%lld",&n,&x,&y);
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum1+=a[i]*i;
sum2+=a[i]*a[i]*i;
mp[a[i]]++;
}
if(x==sum1&&y==sum2)
{
for(i=1;i<=n;i++) // 已经符合目标要求,每个数可任意与其他位置的该数交换(即值相同位置不用任意交换)
{
num=mp[a[i]];
if(num==0)
continue;
ans+=(num*(num-1))/2; //等差数列求和
mp[a[i]]=0;
}
printf("%lld\n",ans);
}
else if(x!=sum1&&y!=sum2&&((y-sum2)%(x-sum1))==0) // 不符合目标要求时,根据公式,除数不能为0即(x-sum1)不为0。而若y==sum2,b=-a也不可能,顺便排除掉减点时间
{
num=(y-sum2)/(x-sum1);
for(i=1;i<=n;i++)
{
b=num-a[i];
if(a[i]!=b&&(x-sum1-(b-a[i])*i)%(a[i]-b)==0) //k一定是整数,不能整数代表不存在,就不计算了,同时得先保证除数不为0
{
k=(x-sum1-(b-a[i])*i)/(a[i]-b);
if(k<=n&&k>=1&&a[k]==b) // 注意要避免越界访问
{
ans++;
}
}
}
printf("%lld\n",ans/2);
}
else
{
printf("0\n");
}
for(i=1;i<=n;i++) //每一次结束都要初始化mp 虽然说跟第一种情况一遍的赋0有点重复,你想节省点时间自然可以把这部直接放二、三情况里边,因为一情况不是主要情况所以我懒改了(时间省不了多少的意思)
mp[a[i]]=0;
}
return 0;
}