链接
题意
数
组
a
通
过
交
换
一
对
数
字
,
得
到
了
b
数
组
。
数组a通过交换一对数字,得到了b数组。
数组a通过交换一对数字,得到了b数组。
给
出
如
下
的
两
个
值
x
=
∑
k
=
1
n
k
a
k
和
y
=
∑
k
=
1
n
k
a
k
2
和
b
数
组
.
给出如下的两个值x = \sum_{k=1}^{n}ka_k和y = \sum_{k=1}^{n}ka^2_k和b数组.
给出如下的两个值x=∑k=1nkak和y=∑k=1nkak2和b数组.
问
可
能
有
多
少
种
交
换
方
式
使
得
满
足
条
件
。
问可能有多少种交换方式使得满足条件。
问可能有多少种交换方式使得满足条件。
x
和
y
的
值
有
可
能
是
和
数
组
不
匹
配
的
,
这
样
的
情
况
时
输
出
0
。
x和y的值有可能是和数组不匹配的,这样的情况时输出0。
x和y的值有可能是和数组不匹配的,这样的情况时输出0。
题解
已
知
x
=
∑
k
=
1
n
k
a
k
和
y
=
∑
k
=
1
n
k
a
k
2
,
已知x = \sum_{k=1}^{n}ka_k和y = \sum_{k=1}^{n}ka^2_k,
已知x=∑k=1nkak和y=∑k=1nkak2,
则
令
x
′
=
∑
k
=
1
n
k
b
k
和
y
′
=
∑
k
=
1
n
k
b
k
2
,
则令x' = \sum_{k=1}^{n}kb_k和y' = \sum_{k=1}^{n}kb^2_k,
则令x′=∑k=1nkbk和y′=∑k=1nkbk2,
假
设
a
i
,
a
j
交
换
成
为
了
b
i
,
b
j
,
即
a
i
=
b
j
,
a
j
=
b
i
。
假设a_i,a_j交换成为了b_i,b_j,即a_i=b_j,a_j=b_i。
假设ai,aj交换成为了bi,bj,即ai=bj,aj=bi。
有
X
=
x
′
−
x
=
i
b
i
+
j
b
j
−
i
a
i
−
j
a
j
=
(
b
i
−
b
j
)
∗
(
i
−
j
)
有X=x'-x=ib_i+jb_j-ia_i-ja_j=(b_i-b_j)*(i-j)
有X=x′−x=ibi+jbj−iai−jaj=(bi−bj)∗(i−j)
有
Y
=
y
′
−
y
=
i
b
i
2
+
j
b
j
2
−
i
a
i
2
−
j
a
j
2
=
(
b
i
2
−
b
j
2
)
∗
(
i
−
j
)
有Y=y'-y=ib_i^2+jb_j^2-ia_i^2-ja_j^2=(b_i^2-b_j^2)*(i-j)
有Y=y′−y=ibi2+jbj2−iai2−jaj2=(bi2−bj2)∗(i−j)
易
得
,
Y
X
=
(
b
i
2
−
b
j
2
)
∗
(
i
−
j
)
(
b
i
−
b
j
)
∗
(
i
−
j
)
=
b
i
+
b
j
=
C
(
常
数
)
易得,\frac{Y}{X}=\frac{(b_i^2-b_j^2)*(i-j)}{(b_i-b_j)*(i-j)}=b_i+b_j=C(常数)
易得,XY=(bi−bj)∗(i−j)(bi2−bj2)∗(i−j)=bi+bj=C(常数)
我
们
知
道
了
两
个
交
换
的
数
之
和
,
则
可
通
过
b
i
求
得
b
j
=
Y
X
−
b
i
,
枚
举
b
i
,
可
求
得
b
j
,
然
后
可
通
过
X
=
(
b
i
−
b
j
)
∗
(
i
−
j
)
得
到
j
的
下
标
i
−
X
b
i
−
b
j
,
只
需
验
证
求
得
的
下
标
j
是
否
满
足
b
j
即
可
。
我们知道了两个交换的数之和,则可通过b_i求得b_j=\frac{Y}{X}-b_i,枚举b_i,可求得b_j,然后可通过X=(b_i-b_j)*(i-j)得到j的下标i-\frac{X}{b_i-b_j},只需验证求得的下标j是否满足b_j即可。
我们知道了两个交换的数之和,则可通过bi求得bj=XY−bi,枚举bi,可求得bj,然后可通过X=(bi−bj)∗(i−j)得到j的下标i−bi−bjX,只需验证求得的下标j是否满足bj即可。
需
要
注
意
的
是
:
需要注意的是:
需要注意的是:
当
X
≠
0
,
Y
%
X
≠
0
时
,
x
,
y
不
匹
配
,
a
n
s
=
0
;
当X \not = 0,Y\%X \not =0时,x,y不匹配,ans=0;
当X=0,Y%X=0时,x,y不匹配,ans=0;
当
X
=
0
,
Y
≠
0
时
,
x
,
y
不
匹
配
,
a
n
s
=
0
;
当X = 0,Y \not = 0时,x,y不匹配,ans=0;
当X=0,Y=0时,x,y不匹配,ans=0;
当
X
=
Y
=
0
时
,
因
为
交
换
前
后
无
变
化
,
则
a
i
=
a
j
,
枚
举
每
个
数
出
现
的
次
数
n
u
m
i
,
a
n
s
=
∑
i
=
1
n
n
u
m
i
∗
(
n
u
m
i
−
1
)
2
当X=Y=0时,因为交换前后无变化,则a_i=a_j,枚举每个数出现的次数num_i,ans=\sum_{i=1}^{n}\frac{num_i*(num_i-1)}{2}
当X=Y=0时,因为交换前后无变化,则ai=aj,枚举每个数出现的次数numi,ans=∑i=1n2numi∗(numi−1)
代码
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
#define ll long long
ll T,n,x,y,c;
ll suma,sumb,sum;
ll a[200500],b[200500];
unordered_map<ll,ll>dyy;
int main(){
cin>>T;
while(T--)
{
cin>>n>>x>>y;
suma=sumb=sum=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];suma+=a[i]*i;
b[i]=a[i]*a[i];sumb+=b[i]*i;
}
x=suma-x;//X
y=sumb-y;//Y
if(x!=0)
{
if(y%x)
{
cout<<0<<endl;
continue;
}
else c=y/x;//c=ai+aj
for(int i=1;i<n;i++)
{
ll aj=c-a[i];
if(a[i]-aj==0)continue;//检查除数a_i-a_j是否为0,因为X>0,为0则跳过
if(x%(a[i]-aj))continue;//防止x和y不匹配
int j=i-x/(a[i]-aj);//计算j的下标
if(j<=i||j>n)continue;//防止重复,对于每个i只查找之后的j
if(a[j]==aj)sum++;
}
}
else
{
if(y!=0)
{
cout<<0<<endl;
continue;
}
dyy.clear();
for(int i=1;i<=n;i++)
{
dyy[a[i]]++;
}
for(auto t:dyy)
sum+=t.second*(t.second-1)/2;
}
cout<<sum<<endl;
}
return 0;
}