1 条题解

  • 0
    @ 2025-8-24 22:19:42

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar NaCly_Fish
    北海虽赊,扶摇可接。

    搬运于2025-08-24 22:19:42,当前版本为作者最后更新于2019-08-27 23:22:09,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    讲道理,这题还是比较简单的。。
    虽然用 Taylor 展开+维护 kk 次方和也可以做,但是可能会 T 掉(
    Taylor 展开直接精度就炸了,,没法做。

    考虑用一种好想又好写的做法:

    sin(a+x)=sinacosx+cosasinx\sin(a+x)=\sin a\cos x+\cos a\sin x cos(a+x)=cosacosxsinasinx\cos(a+x)=\cos a\cos x-\sin a \sin x

    然后随便怎么维护一下就可以了,,

    于是在 Θ(mlogn)\Theta(m \log n) 的复杂度内就能解决。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define reg register
    #define N 200003
    #define ls (u<<1)
    #define rs (u<<1|1)
    #define mid ((l+r)>>1)
    using namespace std;
    
    inline void read(int &x){
        x = 0;
        char c = getchar();
        while(c<'0'||c>'9') c = getchar();
        while(c>='0'&&c<='9'){
            x = (x<<3)+(x<<1)+(c^48);
            c = getchar();
        }
    }
    
    int n,q;
    int a[N];
    double sink,cosk;
    
    struct Segment_Tree{
        double sine[N<<2],cosi[N<<2];
        long long tag[N<<2];
    
        inline void pushup(int u){
            sine[u] = sine[ls]+sine[rs];
            cosi[u] = cosi[ls]+cosi[rs];
        }
    
        inline void update(int u,double sinx,double cosx){
            double sina = sine[u],cosa = cosi[u];
            sine[u] = sina*cosx + cosa*sinx;
            cosi[u] = cosa*cosx - sina*sinx;
        }
    
        inline void pushdown(int u){
            if(!tag[u]) return;
            double sinx = sin(tag[u]),cosx = cos(tag[u]);
            update(ls,sinx,cosx);
            update(rs,sinx,cosx);
            tag[ls] += tag[u];
            tag[rs] += tag[u];
            tag[u] = 0;
        }
    
        void build(int l,int r,int u){
            if(l==r){
                sine[u] = sin(a[l]);
                cosi[u] = cos(a[l]);
                return;
            }
            build(l,mid,ls);
            build(mid+1,r,rs);
            pushup(u);
        }
    
        void modify(int nl,int nr,int l,int r,int u,int k){
            if(nl<=l&&r<=nr){
                update(u,sink,cosk);
                tag[u] += k;
                return;
            }
            pushdown(u);
            if(nl<=mid) modify(nl,nr,l,mid,ls,k);
            if(nr>mid) modify(nl,nr,mid+1,r,rs,k);
            pushup(u);
        }
    
        double query(int nl,int nr,int l,int r,int u){
            if(nl<=l&&r<=nr) return sine[u];
            double res = 0;
            pushdown(u);
            if(nl<=mid) res += query(nl,nr,l,mid,ls);
            if(nr>mid) res += query(nl,nr,mid+1,r,rs);
            return res;
        }
    }T;
    
    int main(){
        int op,l,r,k;
        read(n);
        for(reg int i=1;i<=n;++i) read(a[i]);
        T.build(1,n,1);
        read(q);
        while(q--){
            read(op),read(l),read(r);
            if(op==1){
                read(k);
                sink = sin(k),cosk = cos(k);
                T.modify(l,r,1,n,1,k);
            }else printf("%.1lf\n",T.query(l,r,1,n,1));
        }
        return 0;
    }
    
    • 1

    信息

    ID
    4509
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者