这一题为什么用方差判断等差数列只得了20分
查看原帖
这一题为什么用方差判断等差数列只得了20分
440870
油炸皮卡丘0vo楼主2021/8/25 16:13

思路就是计算这一段区间的方差, 然后求出区间最小值作为首项, 然后求出首项为a, 公差为k, 长度为r-l+1的等差数列的方差, 这个可以直接推公式. 然后判断两个方差是否在误差范围内. 但是这个方法只得了20分, 还是说我写丑了T_T

// -----[今天不努力, 明天变垃圾]-----
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
#define x first
#define y second
const int MAX_N = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
//
//
#define int ll
int n, m;
int a[MAX_N];
struct SegMentTree {
    int l, r;
    int sum1, sum2;
    int mn;
} tree[MAX_N * 4];
#define lc (x * 2)
#define rc (x * 2 + 1)
#define l(x) tree[x].l
#define r(x) tree[x].r
#define sum1(x) tree[x].sum1
#define sum2(x) tree[x].sum2
#define mn(x) tree[x].mn
inline void push_up(int x) {
    sum1(x) = sum1(lc) + sum1(rc);
    sum2(x) = sum2(lc) + sum2(rc);
    mn(x) = min(mn(lc), mn(rc));
}
void build(int x, int l, int r) {
    l(x) = l; r(x) = r;
    if(l == r) {
        sum1(x) = mn(x) = a[l];
        sum2(x) = a[l] * a[l];
        return;
    }
    int mid = (l + r) / 2;
    build(lc, l, mid);
    build(rc, mid + 1, r);
    push_up(x);
}
void update(int x, int k, int val) {
    if(l(x) == r(x)) {
        sum1(x) = mn(x) = val;
        sum2(x) = val * val;
        return;
    }
    int mid = (l(x) + r(x)) / 2;
    if(k <= mid) update(lc, k, val);
    else update(rc, k, val);
    push_up(x);
}
int querymin(int x, int l, int r) {
    if(l(x) >= l && r(x) <= r) {
        return mn(x);
    }
    int mid = (l(x) + r(x)) / 2;
    int ans = INF;
    if(l <= mid) ans = min(ans, querymin(lc, l, r));
    if(r > mid) ans = min(ans, querymin(rc, l, r));
    push_up(x);
    return ans;
}
int querysum1(int x, int l, int r) {
    if(l(x) >= l && r(x) <= r) {
        return sum1(x);
    }
    int mid = (l(x) + r(x)) / 2;
    int ans = 0;
    if(l <= mid) ans += querysum1(lc, l, r);
    if(r > mid) ans += querysum1(rc, l, r);
    push_up(x);
    return ans;
}
int querysum2(int x, int l, int r) {
    if(l(x) >= l && r(x) <= r) {
        return sum2(x);
    }
    int mid = (l(x) + r(x)) / 2;
    int ans = 0;
    if(l <= mid) ans += querysum2(lc, l, r);
    if(r > mid) ans += querysum2(rc, l, r);
    push_up(x);
    return ans;
}
void solve() {
    cin >> n >> m;
    for(int i = 1; i <= n; ++ i) cin >> a[i];
    build(1, 1, n);
    int sumyes = 0;
    while(m -- ) {
        int op, x, y, l, r, k;
        cin >> op;
        if(op == 1) {
            cin >> x >> y;
            x ^= sumyes;
            y ^= sumyes;
            update(1, x, y);
        } else {
            cin >> l >> r >> k;
            l ^= sumyes;
            r ^= sumyes;
            k ^= sumyes;
            int a = querymin(1, l, r); // 首项
            int sum1 = querysum1(1, l, r); // 区间和
            int sum2 = querysum2(1, l, r); // 区间平方和
            int len = (r - l + 1);
            double ave = sum1 * 1.0 / len;
            if(len == 1) {
                cout << "Yes" << '\n';
                ++ sumyes;
                continue;
            }
            double fc1 = sum2 * 1.0 / len - ave * ave;
            double Ave = a + (len - 1) * 1.0 / 2 * k;
            double fc2 = Ave * Ave + a * a + k * k * (len - 1) * (2 * len - 1) * 1.0 / 6 - 2.0 * a * Ave + a * k * (len - 1) - Ave * k * (len - 1);
            if(abs(fc1 - fc2) < eps) {
                cout << "Yes" << '\n';
                ++ sumyes;
            } else {
                cout << "No" << '\n';
            }
        }
    }
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int ZTY = 1;
    //cin >> ZTY;
    while(ZTY -- ) {
        solve();
    }
    return 0;
}
2021/8/25 16:13
加载中...