qinghua大乱斗C

16 篇文章 0 订阅

题意:
维护一个数列,支持两种操作
1.给一个区间所有数加v
2.询问一个区间内所有余弦的和

维护一个余弦和,一个正弦和即可,cosv sinv提出,然后打标记即可~

#include<set>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define RAND() (rand())
using namespace std;
double dc[800005],ds[800005],dcos[800005],dsin[800005];
void Maketree(int k,int l,int r)
{
    dc[k]=1;ds[k]=0;
    if(l==r)
    {
        double x;
        scanf("%lf",&x);
        dsin[k]=sin(x);
        dcos[k]=cos(x);
        return ;
    }
    int m=(l+r)>>1;
    Maketree(k*2,l,m);
    Maketree(k*2+1,m+1,r);
    dsin[k]=dsin[k*2]+dsin[k*2+1];
    dcos[k]=dcos[k*2]+dcos[k*2+1];
}
inline void Add(int k,double sD,double cD)
{
    double Dc=dc[k],Ds=ds[k];
    ds[k]=Dc*sD+Ds*cD;
    dc[k]=Dc*cD-Ds*sD;
    Dc=dcos[k],Ds=dsin[k];
    dsin[k]=Dc*sD+Ds*cD;
    dcos[k]=Dc*cD-Ds*sD;
}
inline void push_down(int k)
{
    Add(k*2,ds[k],dc[k]);
    Add(k*2+1,ds[k],dc[k]);
    dc[k]=1;ds[k]=0;
}
void Update(int k)
{
    dsin[k]=dsin[k*2]+dsin[k*2+1];
    dcos[k]=dcos[k*2]+dcos[k*2+1];
}
void Change(int k,int l,int r,int x,int y,double sD,double cD)
{
    if(x<=l&&y>=r)
    {
        Add(k,sD,cD);
        return ;
    }
    push_down(k);
    int m=(l+r)>>1;
    if (x <= m)
        Change(k*2,l,m,x,y,sD,cD);
    if( y>m)
        Change(k*2+1,m+1,r,x,y,sD,cD);
    /*if(x>m)
        Change(k*2+1,m+1,r,x,y,D);
    else
        if(y<=m)
            Change(k*2,l,m,x,y,D);
        else
        {
            Change(k*2,l,m,x,m,D);
            Change(k*2+1,m+1,r,m+1,y,D);
        }*/
    Update(k);
}
double Query(int k,int l,int r,int x,int y)
{
    if(x<=l&&y>=r)
        return dcos[k];
    push_down(k);
    int m=(l+r)>>1;
    double ans=0;
    if (x <= m)
        ans+=Query(k*2,l,m,x,y);
    if( y>m)
        ans+=Query(k*2+1,m+1,r,x,y);
    /*if(x>m)
        ans=Query(k*2+1,m+1,r,x,y);
    else
        if(y<=m)
            ans=Query(k*2,l,m,x,y);
        else
            ans=Query(k*2,l,m,x,m)+Query(k*2+1,m+1,r,m+1,y);*/
    Update(k);
    return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
#endif
    int T;
    scanf("%d",&T);
    for(int testcase=1;testcase<=T;testcase++)
    {
        printf("Case #%d:\n",testcase);
        int n,m;
        scanf("%d%d",&n,&m);
        Maketree(1,1,n);
        for(int i=1,ch,l,r;i<=m;i++)
        {
            double c;
            scanf("%d",&ch);
            if(ch==1)
            {
                scanf("%d%d%lf",&l,&r,&c);
                Change(1,1,n,l,r,sin(c),cos(c));
            }
            else
            {
                scanf("%d%d",&l,&r);
                printf("%lf\n",Query(1,1,n,l,r));
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值