题目描述
给出一个长度为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;
}