Wannafly挑戰賽22 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(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;
}

 

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