链接:https://www.nowcoder.com/acm/contest/160/D
来源:牛客网
题目描述
给出一个长度为n的整数序列a1,a2,...,an,进行m次操作,操作分为两类。
操作1:给出l,r,v,将al,al+1,...,ar分别加上v;
操作2:给出l,r,询问
输入描述:
第一行一个整数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 cos的联系来解题。
/// sin(x1+ x2) = sinx1*cosx2+ sinx2*cosx1
/// cos(x1+ x2) = cosx1*cosx2- sinx1*sinx2;
/// 复数运算 a+bi * c+ di = (a*c-b*d) + (d*a+c*b)i
/// 复数运算 a+bi + c+di = (a+c) +(c+d)i;
代码:
#include<bits/stdc++.h>
#define lson (i<<1)
#define rson (i<<1|1)
using namespace std;
typedef long long ll;
const int N = 2e5+5;
typedef complex<double > dcom; /// 复数类
/// sin(x1+ x2) = sinx1*cosx2+ sinx2*cosx1
/// cos(x1+ x2) = cosx1*cosx2- sinx1*sinx2;
/// 复数运算 a+bi * c+ di = (a*c-b*d) + (d*a+c*b)i
struct node
{
int l,r;
dcom lz;
dcom sum;
}tr[N<<2];
ll x;
void push_up(int i)
{
tr[i].sum=tr[lson].sum+tr[rson].sum;
}
void push_down(int i)
{
if(tr[i].lz==dcom(1.0,0.0)) return ;
dcom &lz=tr[i].lz;
tr[lson].lz*=lz; tr[rson].lz*=lz;
tr[lson].sum*=lz; tr[rson].sum*=lz;
lz=dcom(1.0,0.0);
}
void build(int i,int l,int r)
{
tr[i].l=l; tr[i].r=r; tr[i].lz=dcom(1.0,0.0); tr[i].sum=dcom(1.0,0.0);
if(l==r){
scanf("%lld",&x);
tr[i].lz=tr[i].sum=dcom(cos(x),sin(x));
return ;
}
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
push_up(i);
return ;
}
void update(int i,int l,int r,dcom val)
{
if(tr[i].l==l&&r==tr[i].r){
tr[i].lz*=val;
tr[i].sum*=val;
return ;
}
push_down(i);
int mid=(tr[i].l+tr[i].r)>>1;
if(r<=mid) update(lson,l,r,val);
else if(l>mid) update(rson,l,r,val);
else{
update(lson,l,mid,val);
update(rson,mid+1,r,val);
}
push_up(i);
}
dcom query(int i,int l,int r)
{
if(l==tr[i].l&&r==tr[i].r){
return tr[i].sum;
}
push_down(i);
int mid=(tr[i].l+tr[i].r)>>1;
if(r<=mid) return query(lson,l,r);
else if(l>mid) return query(rson,l,r);
else{
return query(lson,l,mid)+query(rson,mid+1,r);
}
}
int main()
{
int n,op,l,r,q;
ll val;
scanf("%d",&n);
build(1,1,n);
scanf("%d",&q);
while(q--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d %d %lld",&l,&r,&val);
dcom cc=dcom(cos(val),sin(val));
update(1,l,r,cc);
}
else{
scanf("%d %d",&l,&r);
dcom ans=query(1,l,r);
printf("%.1f\n",ans.imag());
}
}
return 0;
}