嘘~ 正在从服务器偷取页面 . . .

洛谷P6327 区间加区间sin和 题解


洛谷P6327 区间加区间sin和 题解

题目链接:洛谷P6327 区间加区间sin和 题解

题意:维护一个数据结构,支持

  1. 区间加 \(v\)
  2. 询问区间 \(\sum\limits_{i=1}^{r}\sin a_i\)

注意到 \[ \begin{aligned} \sin(a+x)&=\sin a\cos x+\cos a \sin x\\ \cos(a+x)&=\cos a\cos x-\sin a \sin x \end{aligned} \] 直接维护即可两个量即可

注意点

  1. 更新的时候拿之前更新过的sin去更新cos,爆零。
  2. 不开long long,爆零。
  3. 不下传标记,爆零。
  4. 可以适当卡卡常(逃

代码如下

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define N (int)(2e5+15)
#define ls(at) (at<<1)
#define rs(at) (at<<1|1)
namespace FastIO
{
    #define gc() readchar()
    #define pc(a) putchar(a)
    #define SIZ (int)(1e6+15)
    char buf1[SIZ],*p1,*p2;
    char readchar()
    {
        if(p1==p2)p1=buf1,p2=buf1+fread(buf1,1,SIZ,stdin);
        return p1==p2?EOF:*p1++;
    }
    template<typename T>void read(T &k)
    {
        char ch=gc();T x=0,f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=gc();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
        k=x*f;
    }
    template<typename T>void write(T k)
    {
        if(k<0){k=-k;pc('-');}
        static T stk[66];T top=0;
        do{stk[top++]=k%10,k/=10;}while(k);
        while(top){pc(stk[--top]+'0');}
    }
}using namespace FastIO;
// #define double long double
// const double eps=1e-15;
double sinx[N<<2],cosx[N<<2];
int tag[N<<2];
int n,m,a[N];
void push_up(int at)
{
    sinx[at]=sinx[ls(at)]+sinx[rs(at)];
    cosx[at]=cosx[ls(at)]+cosx[rs(at)];
}
void build(int l,int r,int at)
{
    if(l==r)
    {
        sinx[at]=sin(a[l]);
        cosx[at]=cos(a[l]);
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,ls(at));
    build(mid+1,r,rs(at));
    push_up(at);
}
void proc(int at,int k)
{
    double sink=sin(k),cosk=cos(k);
    double sina=sinx[at],cosa=cosx[at];
    sinx[at]=sina*cosk+cosa*sink;
    cosx[at]=cosa*cosk-sina*sink;
    tag[at]+=k;
}
void push_down(int at)
{
    int k=tag[at];
    if(k)
    {
        proc(ls(at),k);
        proc(rs(at),k);
        tag[at]=0;
    }
}
void update(int nl,int nr,int l,int r,int k,int at)
{
    if(nl<=l&&r<=nr)
    {
        proc(at,k);
        return;
    }
    int mid=(l+r)>>1;
    push_down(at);
    if(nl<=mid)update(nl,nr,l,mid,k,ls(at));
    if(nr>mid)update(nl,nr,mid+1,r,k,rs(at));
    push_up(at);
}
double query(int nl,int nr,int l,int r,int at)
{
    if(nl<=l&&r<=nr)return sinx[at];
    if(nl>r||nr<l)return 0;
    push_down(at);
    int mid=(l+r)>>1;
    return query(nl,nr,l,mid,ls(at))+query(nl,nr,mid+1,r,rs(at));
}
signed main()
{
    // ios::sync_with_stdio(0);
    // cin.tie(0);cout.tie(0);
    // cout << fixed << setprecision(1);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    read(n);
    for(int i=1; i<=n; i++)
        read(a[i]);
    build(1,n,1);
    int Q;read(Q);
    int op,l,r,v;
    while(Q--)
    {
        read(op);read(l);read(r);
        if(op==1){read(v);update(l,r,1,n,v,1);}
        else printf("%.1lf\n",query(l,r,1,n,1));
    }
    return 0;
}

文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录