社区讨论

评测机全RE

P6327区间加区间 sin 和参与者 4已保存回复 48

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
41 条
当前快照
1 份
快照标识符
@mjbbs5v2
此快照首次捕获于
2025/12/18 18:56
2 个月前
此快照最后确认于
2025/12/20 18:00
2 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5 + 10;

int n, m;
int a[N], c;

struct Tree{
	int ls, rs;
	int val, tag;
	double sin_s, cos_s;
	
	#define ls(p) tr[p].ls
	#define rs(p) tr[p].rs
	#define val(p) tr[p].val
	#define tag(p) tr[p].tag
	#define c(p) tr[p].cos_s
	#define s(p) tr[p].sin_s
}tr[N << 2];

void pushup(int p){
	s(p) = s(p << 1) + s(p << 1 | 1);
	c(p) = c(p << 1) + c(p << 1 | 1);
}

//sin(a + b) = sin(a)cos(b) + sin(b)cos(a)
double Sin(int a, int b){
	return s(a) * cos(b) + c(a) * sin(b);
}

double Cos(int a, int b){
	return c(a) * cos(b) - s(a) * sin(b);
}

void pushdown(int p){
	if(tag(p)){
		s(p << 1) = Sin(val(p << 1), tag(p));
		c(p << 1) = Cos(val(p << 1), tag(p));
		
		s(p << 1 | 1) = Sin(val(p << 1 | 1), tag(p));
		c(p << 1 | 1) = Cos(val(p << 1 | 1), tag(p));
		
		tag(p << 1) += tag(p), tag(p << 1 | 1) += tag(p);
		tag(p) = 0;
	}
}

void build(int p, int l, int r){
	tr[p] = {l, r, 0, 0, 0, 0};
	
	if(l == r){
		val(p) = a[l];
		s(p) = sin(a[l]), c(p) = cos(a[l]);
		return;
	}
	int mid = l + r >> 1;
	build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
	
	pushup(p);
}

void update(int p, int l, int r, int v){
	int L = ls(p), R = rs(p);
	if(l <= L && R <= r){
		val(p) += v;
		tag(p) += v;
		s(p) = sin(val(p));
		c(p) = cos(val(p));
		return;
	}
	pushdown(p);
	
	int mid = L + R >> 1;
	if(l <= mid) update(p << 1, l, r, v);
	if(r > mid) update(p << 1 | 1, l, r, v);
	
	pushup(p);
}

double query(int p, int l, int r){
	int L = ls(p), R = rs(p);
	if(l <= L && R <= r) return s(p);
	pushdown(p);
	
	int mid = L + R >> 1;
	double res = 0;
	if(l <= mid) res += query(p << 1, l, r);
	if(r > mid) res += query(p << 1 | 1, l, r);
	
	return res;
}

inline int read(){
	int x = 0, f = 1;
	char ch = getchar();
	while(ch < '0' || '9' < ch){
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while('0' <= ch && ch <= '9'){
		x = x * 10ll + ch - '0';
		ch = getchar();
	}
	
	return f * x;
}

signed main(){
	n = read();
	for(int i = 1; i <= n; ++i) a[i] = read();
	build(1, 1, n);
	
	m = read();
	while(m--){
		int opt = read(), l = read(), r = read();
		if(opt == 1){
			c = read();
			update(1, l, r, c);
		}
		else printf("%.1lf\n", query(1, l, r));
	}
	
	return 0;
}

回复

48 条回复,欢迎继续交流。

正在加载回复...