题意:数组a通过交换一对数字,得到了b数组,给出x=∑nk=1kak和y=∑nk=1ka2k和b数组,问有多少对l,r(l<=r)能满足条件
思路:
假设交换了 (i,j),那么:i*a[i] -> i*a[j],j*a[j] -> j*a[i]
因此对于原来的 x、y 有:
可以得到:
将得到的两个式子相除,有:
第一个式子可以化简为 X−x=(ai−aj)∗(j−i)
- 第一个式子左边为一个定值,所以ai和aj一一对应,可以枚举a数组
- 第二个数组可以化为X2−X1+(bj−bi)ibj−bi=j,假设j>i(方便计数),枚举ai通过式子一可以计算aj,然后通过式子二可以计算出j,判一下aj是否等于j
- X2−X1=0,Y2−Y1≠0,则不合法
- X2−X1=0,Y2−Y1=0推出ai=aj,j≠i
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #define ll long long #define N 0x3f3f3f3f using namespace std; ll a[100010]; int main() { int t; scanf("%d",&t); while(t--) { int n; map<ll,ll>mp; ll x,y; scanf("%d%lld%lld",&n,&x,&y); ll x1=0,y1=0; ll minn=N; for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); mp[a[i]]++; x1=x1+i*a[i]; y1=y1+i*a[i]*a[i]; } ll A=x1-x,B=y1-y;; if(A==0) { if(B!=0) { cout<<0<<endl; continue; } ll sum=0; map<ll,ll>::iterator it; for(it=mp.begin();it!=mp.end();it++) { sum+=((it->second)-1)*(it->second)/2; } printf("%lld\n",sum); continue; } if(B%A) { printf("0\n"); continue; } ll dt=B/A,sum=0; for(int i=1;i<=n;i++) { ll aj=dt-a[i]; if(aj==a[i]) continue; ll j=(A+(aj-a[i])*i)/(aj-a[i]); if(j<=i||j>n) continue; if(a[j]==aj) sum++; } printf("%lld\n",sum); } return 0; }
不知道为啥 数组a 我定义成int类型的就wa 0.0 明明数组范围是 10^6