P6327 區間加區間sin和 線段樹

這題挺簡單的  不過錯的很玄學

用公式 sin(a+x)=sina*cosx+sinx*cosa cos(a+x)=cosa*cosx-sina*sinx就行 維護sinx的和和cosx的和更新就行了  需要注意的是常數比較大  三角函數的值儘量只算一次 傳遞下去就行 然後玄學的地方是 我把lazy[x]+=val;放到cal函數裏面會wa  把它單獨拿出來寫就能過 不知道爲什麼

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define Ri register int
#define ls id<<1
#define rs ls|1
#define lson ls,l,mid
#define rson rs,mid+1,r
using namespace std;
const int N = 2e5+10;
typedef long long ll;
double sine[N<<2],cosi[N<<2];
int a[N];
ll lazy[N<<2];
inline int in(){
	Ri w=0,x=0;char c=0;
	while(c>'9'||c<'0') w|=c=='-',c=getchar();
	while(c<='9'&&c>='0') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return w?-x:x;
}
inline void pushup(int id){
    sine[id] = sine[ls]+sine[rs];
    cosi[id] = cosi[ls]+cosi[rs];
}
inline void cal(Ri x,double sinv,double cosv){
	double sina=sine[x],cosa=cosi[x];
	sine[x]=sina*cosv+cosa*sinv;
	cosi[x]=cosa*cosv-sina*sinv;
}
inline void pushdown(Ri id){
	if(lazy[id]){
		double sinv=sin(lazy[id]),cosv=cos(lazy[id]);
		cal(ls,sinv,cosv);
		cal(rs,sinv,cosv);
		lazy[ls]+=lazy[id];
		lazy[rs]+=lazy[id];
		lazy[id]=0;
	}
}
void build(Ri id,Ri l,Ri r){
	if(l==r){
		sine[id]=sin(a[l]);
		cosi[id]=cos(a[l]);
		return;
	}
	int mid = l+r>>1;
	build(lson);build(rson);
	pushup(id);
}
void update(Ri id,Ri l,Ri r,Ri L,Ri R,Ri val){
	if(L<=l&&R>=r){
		cal(id,sin(val),cos(val));
		lazy[id]+=val;
		return;
	}
	pushdown(id);
	int mid = l+r>>1;
	if(L<=mid) update(lson,L,R,val);
	if(R>mid) update(rson,L,R,val);
	pushup(id);
}
double query(Ri id,Ri l,Ri r,Ri L,Ri R){
	if(L<=l&&R>=r){
		return sine[id];
	}
	int mid = l+r>>1;
	double ret = 0;
	pushdown(id);
	if(L<=mid) ret+=query(lson,L,R);
	if(R>mid) ret+=query(rson,L,R);
	return ret;
}
int main(){
	int n;
	n=in();
	for(int i = 1; i <= n; i++) a[i]=in();
	build(1,1,n);
	int m;
	scanf("%d",&m);
	for(Ri i = 1; i <= m; i++){
		Ri op,l,r,x;
		op=in(); 
		if(op==1){
			l=in(),r=in(),x=in();
			update(1,1,n,l,r,x);
		}else{
			l=in(),r=in();
			printf("%.1lf\n",query(1,1,n,l,r));
		}
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章