链接:https://www.nowcoder.com/acm/contest/160/D
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
给出一个长度为
的整数序列
,进行
次操作,操作分为两类。
操作1:给出
,将
分别加上
;
操作2:给出
,询问
输入描述:
第一行一个整数
接下来一行
个整数表示
接下来一行一个整数
接下来
行,每行表示一个操作,操作1表示为
,操作2表示为
保证
是整数
输出描述:
对每个操作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
思路:利用公式
然后更新操作的话,可以用懒惰标记,并利用上面2个公式更新答案
#include<bits/stdc++.h>
using namespace std;
const int MOD=1e9+7;
const int MAX=2e5+10;
const double PI=acos(-1.0);
typedef long long ll;
int a[MAX];
struct lenka
{
int l,r;
ll tag;
double sinum,cosum;
}A[MAX<<2];
void build(int k,int l,int r)
{
A[k].l=l,A[k].r=r;
A[k].tag=0;
if(l==r)
{
A[k].sinum=sin(1.0*a[r]);
A[k].cosum=cos(1.0*a[r]);
return;
}
build(2*k,l,(l+r)/2);
build(2*k+1,(l+r)/2+1,r);
A[k].sinum=A[2*k].sinum+A[2*k+1].sinum;
A[k].cosum=A[2*k].cosum+A[2*k+1].cosum;
}
void add(int k,int x,int y,ll z)
{
if(x==A[k].l&&y==A[k].r)
{
double C=cos(z);
double S=sin(z);
double SIN=A[k].sinum*C+A[k].cosum*S;
double COS=A[k].cosum*C-A[k].sinum*S;
A[k].sinum=SIN;
A[k].cosum=COS;
if(x!=y)A[k].tag+=z;
return;
}
if(A[k].tag)
{
add(2*k,A[2*k].l,A[2*k].r,A[k].tag);
add(2*k+1,A[2*k+1].l,A[2*k+1].r,A[k].tag);
A[k].tag=0;
}
if(y<=A[2*k].r)add(2*k,x,y,z);
else if(x>=A[2*k+1].l)add(2*k+1,x,y,z);
else
{
add(2*k,x,A[2*k].r,z);
add(2*k+1,A[2*k+1].l,y,z);
}
A[k].sinum=A[2*k].sinum+A[2*k+1].sinum;
A[k].cosum=A[2*k].cosum+A[2*k+1].cosum;
}
double ask(int k,int x,int y)
{
if(x==A[k].l&&y==A[k].r)return A[k].sinum;
if(A[k].tag)
{
add(2*k,A[2*k].l,A[2*k].r,A[k].tag);
add(2*k+1,A[2*k+1].l,A[2*k+1].r,A[k].tag);
A[k].tag=0;
}
double sum=0;
if(y<=A[2*k].r)sum=ask(2*k,x,y);
else if(x>=A[2*k+1].l)sum=ask(2*k+1,x,y);
else sum=ask(2*k,x,A[2*k].r)+ask(2*k+1,A[2*k+1].l,y);
return sum;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build(1,1,n);
int m;
cin>>m;
while(m--)
{
int op,x,y;
ll z;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
scanf("%lld",&z);
add(1,x,y,z);
}
else printf("%.1f\n",ask(1,x,y));
}
return 0;
}