实在看不出来 求助
  • 板块P6688 可重集
  • 楼主_xiyan
  • 当前回复5
  • 已保存回复5
  • 发布时间2020/7/29 16:00
  • 上次更新2023/11/6 21:51:30
查看原帖
实在看不出来 求助
238370
_xiyan楼主2020/7/29 16:00

卡这道题两天了,从学大佬用hash到学大佬用正余弦,从全红到现在4个红。能力有限,实在看不出来哪里错了,求大佬指点一下


#include <cmath>
#include <cctype>
#include <cstdio>
#include <cstring>
#define double long double
#define lowbit(x) (x & -x)

inline int read() {
    int x = 0, w = 1;
    int ch = getchar();
    while (!isdigit(ch)) {
        if (ch == 45) w = -1;
        ch = getchar();
    }
    while (isdigit(ch)) {
        x = x * 10 + ch - 48;
        ch = getchar();
    }
    return x * w;
}

// 浮点数判等
inline bool equal(double x, double y) {
    // return fabs(x - y) < 0.000000001;
    return fabs(x - y) < 0.00001;
}

// 2<<20
const int arr_size = 1050000;
// 存放原来的数
int a[arr_size];

struct Node {
    // 数值和
    long long sum;
    // 正弦和
    double sinn;
    // 余弦和
    double coss;

    Node () {}

    Node (long long sum, double sinn, double coss) {
        this->sum = sum;
        this->sinn = sinn;
        this->coss = coss;
    }

    Node operator + (const Node& t) const {
        return Node(this->sum + t.sum, this->sinn + t.sinn, this->coss + t.coss);
    }

    Node operator - (const Node& t) const {
        return Node(this->sum - t.sum, this->sinn - t.sinn, this->coss - t.coss);
    }
} arr[arr_size];

// 树状树组更新
inline void update(long long val, int index) {
    // val-a[index] : 数值变化
    // sin(val)-sin(a[index]) : 正弦值变化
    // cos(val)-cos(a[index]) : 余弦值变化
    Node c (val-a[index], sin(val)-sin(a[index]), cos(val)-cos(a[index]));
    // 记录新值用于后续更新
    a[index] = val;
    // 普通更新
    for ( ; index < arr_size; index += lowbit(index)) arr[index] = arr[index] + c;
}

// 树状树组建树
inline void build(int n) {
    int i, j;
    // for (i = 0; i < arr_size; i++) arr[i] = Node(0, 0 ,0);
    for (i = 1; i <= n; i++) {
        a[i] = read();
        Node c (a[i], sin(a[i]), cos(a[i]));
        // 向上更新贡献
        for (j = i; j < arr_size; j += lowbit(j)) arr[j] = arr[j] + c;
    }
}

// 获取 1~index 数值和 正弦和 余弦和
inline Node get(int index) {
    Node ans (0LL, 0, 0);
    for ( ; index; index ^= lowbit(index)) ans = ans + arr[index];
    return ans;
}

// 获取 lef~rig 数值和 正弦和 余弦和
inline Node get(int lef, int rig) {
    Node node1 = get(rig) - get(lef-1);
    return node1;
}

inline void exist(int r2, int l2, int r1, int l1) {
    Node node1 = get(r1) - get(l1-1);
    Node node2 = get(r2) - get(l2-1);
    // 区间差值的和
    int dif = node1.sum - node2.sum;
    // 总差值若不是区间数的倍和数则肯定无解
    if (dif % (r2 - l2 + 1)) {
        printf("NO\n");
        return;
    }
    // 获取单个数差值
    dif /= (r2 - l2 + 1);
    double sinn = sin(dif);
    double coss = cos(dif);
    // sin(x+k) = sin(x) * cos(k) + cos(x) * sin(k)
    bool equal1 = equal(node1.sinn, node2.sinn * coss + node2.coss * sinn);
    // cos(x+k) = cos(x) * cos(k) - sin(x) * sin(k)
    bool equal2 = equal(node1.coss, node2.coss * coss - node2.sinn * sinn);
    if (equal1 && equal2) printf("YES\n");
    else printf("NO\n");
}

int main() {
    int n = read();
    int m = read();
    build(n);
    while (m--) {
        if(read()) exist(read(), read(), read(), read());
        else update(read(), read());
    }
    return 0;
}

提交记录

2020/7/29 16:00
加载中...