牛客网 整数序列 (线段树+complex 类)

链接: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;
}

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/81808036