题目描述
给出一个长度为n的整数序列a1,a2,…,an,进行m次操作,操作分为两类。
操作1:给出l,r,v,将al,al+1,…,ar分别加上v;
操作2:给出l,r,询问sigma sin
输入描述:
第一行一个整数n
接下来一行n个整数表示a1,a2,…,an
接下来一行一个整数m
接下来m行,每行表示一个操作,操作1表示为1 l r v,操作2表示为2 l r
保证1≤n,m,ai,v≤200000;1≤l≤r≤n,v是整数
输出描述:
对每个操作2,输出一行,表示答案,四舍五入保留一位小数
保证答案的绝对值大于0.1,且答***值的小数点后第二位不是4或5
数据随机生成(n,m人工指定,其余整数在数据范围内均匀选取),并去除不满足条件的操作2
示例1
输入
复制
4
1 2 3 4
5
2 2 4
1 1 3 1
2 2 4
1 2 4 2
2 1 3
输出
复制
0.3
-1.4
-0.3


根据
sin(a+b) = sin(a) * cos(b) + cos(a) * sin(b)
cos(a+b) = cos(a) *cos(b) - sin(a) * sin(b)

维护即可。


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int n,m;
struct node{
	int l,r;	double Cos,Sin,lazy;
}t[N<<2];
inline void push_up(int p){
	t[p].Sin=t[p<<1].Sin+t[p<<1|1].Sin;
	t[p].Cos=t[p<<1].Cos+t[p<<1|1].Cos;
}
inline void push_down(int p){
	if(t[p].lazy!=0.0){
		t[p<<1].lazy+=t[p].lazy; t[p<<1|1].lazy+=t[p].lazy;
		double x=t[p<<1].Sin,y=t[p<<1].Cos;
		t[p<<1].Sin=x*cos(t[p].lazy)+y*sin(t[p].lazy);
		t[p<<1].Cos=y*cos(t[p].lazy)-x*sin(t[p].lazy);
		x=t[p<<1|1].Sin,y=t[p<<1|1].Cos;
		t[p<<1|1].Sin=x*cos(t[p].lazy)+y*sin(t[p].lazy);
		t[p<<1|1].Cos=y*cos(t[p].lazy)-x*sin(t[p].lazy);		
		t[p].lazy=0.0;
	}
}
void build(int p,int l,int r){
	t[p].l=l; t[p].r=r; t[p].lazy=0.0;
	if(l==r){
		double x; scanf("%lf",&x); t[p].Sin=sin(x); t[p].Cos=cos(x); return ;
	}
	int mid=l+r>>1;
	build(p<<1,l,mid);	build(p<<1|1,mid+1,r);
	push_up(p);
}
void change(int p,int l,int r,int v){
	if(t[p].l==l&&t[p].r==r){
		double x=t[p].Sin,y=t[p].Cos;
		t[p].Sin=x*cos(v*1.0)+y*sin(v*1.0);
		t[p].Cos=y*cos(v*1.0)-x*sin(v*1.0);
		t[p].lazy+=1.0*v; return ;
	}
	push_down(p);	int mid=t[p].l+t[p].r>>1;
	if(r<=mid)	change(p<<1,l,r,v);
	else if(l>mid)	change(p<<1|1,l,r,v);
	else	change(p<<1,l,mid,v),change(p<<1|1,mid+1,r,v);
	push_up(p);
}
double ask(int p,int l,int r){
	if(t[p].l==l&&t[p].r==r)	return t[p].Sin;
	push_down(p);	int mid=t[p].l+t[p].r>>1;
	if(r<=mid)	return ask(p<<1,l,r);
	else if(l>mid)	return ask(p<<1|1,l,r);
	else	return ask(p<<1,l,mid)+ask(p<<1|1,mid+1,r);
}
signed main(){
	cin>>n;	build(1,1,n);	cin>>m;
	while(m--){
		int op,l,r,v;	scanf("%d %d %d",&op,&l,&r);
		if(op==1)	scanf("%d",&v),change(1,l,r,v);
		else	printf("%.1lf\n",ask(1,l,r));
	}
	return 0;
}