Wannafly挑战赛22 D 整数序列

版权声明:转载请说明出处 https://blog.csdn.net/bao___zi/article/details/81940754

题目描述

给出一个长度为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(a[i])+isin(a[i])

那么当我们需要进行操作1的时候,我们只需要将那个数也拆成这样进行乘法运算就行,然后我们最后查询的时候我们只需要查区间的和的虚部就行。

Ps: real() 这个是实根

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<complex>
using namespace std;
const int maxn=2e5+10;
#define mem(a,b) memset(a,b,sizeof(a))
typedef complex<double> E;
int n,m,a[maxn];
E sum[maxn<<2],lz[maxn<<2];
void pushup(int k){
	sum[k]=sum[k<<1]+sum[k<<1|1];
}
void pushdown(int k){
	sum[k<<1]*=lz[k];lz[k<<1]*=lz[k];
	sum[k<<1|1]*=lz[k];lz[k<<1|1]*=lz[k];
	lz[k]=E(1,0);
}
void build(int l,int r,int k){
	lz[k]=E(1,0);
	if(l==r){
		sum[k]=E(cos(a[l]),sin(a[l]));
		return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,k<<1);build(mid+1,r,k<<1|1);
	pushup(k);
}
void cha(int l,int r,int ql,int qr,E x,int k){
	if(l==ql&&r==qr){
		sum[k]*=x;
		lz[k]*=x;
		return ;
	}
	int mid=(l+r)>>1;
	pushdown(k);
	if(qr<=mid) cha(l,mid,ql,qr,x,k<<1);
	else if(ql>mid) cha(mid+1,r,ql,qr,x,k<<1|1);
	else cha(l,mid,ql,mid,x,k<<1),cha(mid+1,r,mid+1,qr,x,k<<1|1);
	pushup(k);
}
double query(int l,int r,int ql,int qr,int k){
	if(l==ql&&r==qr){
		return sum[k].imag();
	}
	int mid=(l+r)>>1;
	pushdown(k);
	if(qr<=mid) return query(l,mid,ql,qr,k<<1);
	else if(ql>mid) return query(mid+1,r,ql,qr,k<<1|1);
	else return query(l,mid,ql,mid,k<<1)+query(mid+1,r,mid+1,qr,k<<1|1);
}
int main(){
	int i,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++) scanf("%d",&a[i]);
	build(1,n,1);
	scanf("%d",&m);
	while(m--){
		int ki,u,v,w;
		scanf("%d",&ki);
		if(ki==1){
			scanf("%d%d%d",&u,&v,&w);
			cha(1,n,u,v,E(cos(w),sin(w)),1);
		}
		else{
			scanf("%d%d",&u,&v);
			printf("%.1lf\n",query(1,n,u,v,1));
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/bao___zi/article/details/81940754
今日推荐