卡这道题两天了,从学大佬用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;
}