The 16th Zhejiang Provincial Collegiate Programming Contest - B Element Swapping(zoj4101)

思路:

dx=(i*b[i]+j*b[j])-(i*b[j]+j*b[i])=(i-j)*(b[i]-b[j])

   同理  dy=(i-j)*(b[i]^2-b[j]^2)=dx*(b[i]+b[j])直接枚举i 将求出的 b[j]=dy/dx-b[i] 带入上面第一个式子求出 j,判断 b[j]和求出的是否一致。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
ll t, n, a[N], x, y, cnt[N];
int main() {
    scanf("%lld", &t);
    while(t--) {
        scanf("%lld%lld%lld", &n, &x, &y);
        ll A = 0, B = 0, ans = 0;
        memset(cnt, 0, sizeof cnt);
        for(int i = 1; i <= n; i++) {
            scanf("%lld", a + i);
            A += (ll)i * (ll)a[i];
            B += (ll)i * (ll)a[i] * a[i];
        }
        x = A - x, y = B - y;
        if(y == 0) {
            for(int i = 1; i <= n; i++) {//同样的数字可以互相换
                ans += cnt[a[i]];
                cnt[a[i]]++;
            }
        } else if(x != 0) {
            if(y % x == 0) {
                y /= x;//a[j]=y/x-a[i];
                for(int i = 1; i <= n; i++) {
                    ll k = a[i] - (y - a[i]);//k=a[i]-a[j];
                    if(k && x % k == 0) {//题中给出1<=bi<=1e5;x=(j-i)*(a[i]-a[j]);
                        ll u = i - x / k;//u=i-(i-j)=j
                        if(u >= 1 && u < i && a[u] == y - a[i])//a[j]+a[i]==y
                            ans++;
                    }
                }
            }
        }
        printf("%lld\n", ans);
    }
    return 0 ;
}

猜你喜欢

转载自blog.csdn.net/Endeavor_G/article/details/89641938