• 洛谷 P6327 区间加区间sin和


    洛谷 P6327 区间加区间sin和

    洛谷传送门

    题目描述

    给出一个长度为 nn 的整数序列 a_1,a_2,ldots,a_na1,a2,…,a**n,进行 mm 次操作,操作分为两类。

    操作 11:给出 l,r,vl,r,v,将 a_l,a_{l+1},ldots,a_ra**l,a**l+1,…,a**r 分别加上 vv

    操作 22:给出 l,rl,r,询问 sumlimits_{i=l}^{r}sin(a_i)i=lrsin(a**i)。

    输入格式

    第一行一个整数 nn

    接下来一行 nn 个整数表示 a_1,a_2,ldots,a_na1,a2,…,a**n

    接下来一行一个整数 mm

    接下来 mm 行,每行表示一个操作,操作 11 表示为 1 l r v,操作 22 表示为 2 l r

    输出格式

    对每个操作 22,输出一行,表示答案,四舍五入保留一位小数。

    保证答案的绝对值大于 0.10.1,且答案的准确值的小数点后第二位不是 44 或 55。


    题解:

    看到区间带修就想线段树啊。但是这道题怎么维护加权之后的sin值呢?

    这就需要用到高一学的三角函数的和差角函数。

    和差角函数不会的请走百度百科。

    所以线段树维护一个cos值一个sin值,在打lazy标记的时候把两个值同时更新,就可以得到正确答案啦。

    剩下的就是裸的线段树。

    关于线段树,不会的可以走:简单线段树知识点详解

    如同部分题目不开longlong见祖宗一样。这道题也需要double,注意精度损失。

    代码:

    #include<cstdio>
    #include<cmath>
    #define lson pos<<1
    #define rson pos<<1|1
    using namespace std;
    const int maxn=2e5+5;
    int n,m;
    double a[maxn];
    double cs[maxn<<2],sn[maxn<<2];
    double lazy[maxn<<2];
    void build(int pos,int l,int r)
    {
    	int mid=(l+r)>>1;
    	if(l==r)
    	{
    		sn[pos]=sin(a[l]);
    		cs[pos]=cos(a[l]);
    		return;
    	}
    	build(lson,l,mid);
    	build(rson,mid+1,r);
    	sn[pos]=sn[lson]+sn[rson];
    	cs[pos]=cs[lson]+cs[rson];
    }
    void mark(int pos,int l,int r,double k)
    {
    	double snn=sn[pos],css=cs[pos];
    	sn[pos]=(snn*cos(k)+css*sin(k));
    	cs[pos]=(css*cos(k)-snn*sin(k));
    	lazy[pos]+=k;
    }
    void pushdown(int pos,int l,int r)
    {
    	int mid=(l+r)>>1;
    	mark(lson,l,mid,lazy[pos]);
    	mark(rson,mid+1,r,lazy[pos]);
    	lazy[pos]=0;
    }
    void update(int pos,int l,int r,int x,int y,double k)
    {
    	int mid=(l+r)>>1;
    	if(x<=l && r<=y)
    	{
    		mark(pos,l,r,k);
    		return;
    	}
    	if(lazy[pos])
    		pushdown(pos,l,r);
    	if(x<=mid)
    		update(lson,l,mid,x,y,k);
    	if(y>mid)
    		update(rson,mid+1,r,x,y,k);
    	sn[pos]=sn[lson]+sn[rson];
    	cs[pos]=cs[lson]+cs[rson];
    }
    double query(int pos,int l,int r,int x,int y)
    {
    	double ret=0;
    	int mid=(l+r)>>1;
    	if(x<=l && r<=y)
    		return sn[pos];
    	if(lazy[pos])
    		pushdown(pos,l,r);
    	if(x<=mid)
    		ret+=query(lson,l,mid,x,y);
    	if(y>mid)
    		ret+=query(rson,mid+1,r,x,y);
    	return ret;
    }
    int main()
    {
    	// freopen("gold.in","r",stdin);
    	// freopen("gold.out","w",stdout);
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%lf",&a[i]);
    	build(1,1,n);
    	scanf("%d",&m);
    	for(int i=1;i<=m;i++)
    	{
    		int opt,x,y;
    		double v;
    		scanf("%d%d%d",&opt,&x,&y);
    		if(opt==1)
    		{
    			scanf("%lf",&v);
    			update(1,1,n,x,y,v);
    		}
    		else
    			printf("%.1lf
    ",query(1,1,n,x,y));
    	}
    	return 0;
    }
    
  • 相关阅读:
    MVC5 Controller构造方法获取User为空解决方法
    js删除Array数组中的某个元素
    VS2015 工具箱 保存位置
    Mapper 赋值对应实体属性
    cookieHelper
    python3练习100题——007
    python3练习100题——006
    python3练习100题——005
    python3练习100题——004
    python3练习100题——003
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14023496.html
Copyright © 2020-2023  润新知