连着19发0分的惨剧
查看原帖
连着19发0分的惨剧
80026
walk_alone楼主2021/1/15 16:14

先是RE后是WA……蒟蒻已经心态爆炸

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct node
{
    double sin_sum;
    double cos_sum;
    long long tag;
};
struct node t[800005];
long long a[200005];
void build(int place,int left,int right)
{
    if(left==right)
    {
        t[place].sin_sum = sin((double)a[left]);
        t[place].cos_sum = cos((double)a[left]);
        return;
    }
    int mid = (left + right) >> 1;
    build(place << 1, left, mid);
    build(place << 1 | 1, mid + 1, right);
    t[place].sin_sum = t[place << 1].sin_sum + t[place << 1 | 1].sin_sum;
    t[place].cos_sum = t[place << 1].cos_sum + t[place << 1 | 1].cos_sum;
    return;
}
void update(int place, double sinx, double cosx)
{
    double sinsum = t[place].sin_sum, cossum = t[place].cos_sum;
    t[place].sin_sum = sinsum * cosx + cossum * sinx;
    t[place].cos_sum = cossum * cosx - sinsum * sinx;
    return;
}
void pushdown(int place,int left,int right)
{
    if(t[place].tag)
    {
        double sinx = sin((double)t[place].tag), cosx = cos((double)t[place].tag);
        update(place << 1, sinx,cosx);
        update(place << 1 | 1, sinx, cosx);
        t[place << 1].tag += t[place].tag;
        t[place << 1 | 1].tag += t[place].tag;
        t[place].tag = 0;
    }
    return;
}
void change(int place,int left,int right,int start,int end,long long x,double sinx,double cosx)
{
    if(start<=left && right<=end)
    {
        update(place, sinx, cosx);
        t[place].tag += x;
        return;
    }
    pushdown(place, left, right);
    int mid = (left + right) >> 1;
    if(start<=mid)
        change(place << 1, left, mid, start, end, x, sinx, cosx);
    if(end>mid)
        change(place << 1 | 1, mid + 1, right, start, end, x, sinx, cosx);
    t[place].sin_sum = t[place << 1].sin_sum + t[place << 1 | 1].sin_sum;
    t[place].cos_sum = t[place << 1].cos_sum + t[place << 1 | 1].cos_sum;
    return;
}
double query(int place,int left,int right,int start,int end)
{
    if(start<=left && right<=end)
        return t[place].sin_sum;
    int mid = (left + right) >> 1;
    double ans = 0;
    if(start<=mid)
        ans += query(place << 1, left, mid, start, end);
    if(end>mid)
        ans += query(place << 1 | 1, mid + 1, right, start, end);
    return ans;
}
int main()
{
    int n, m, op, left, right;
    long long x;
    scanf("%d", &n);
    for (int i = 1; i <= n;i++)
        scanf("%lld", &a[i]);
    build(1, 1, n);
    scanf("%d", &m);
    for (int i = 1; i <= m;i++)
    {
        scanf("%d%d%d", &op, &left, &right);
        if(op==1)
        {
            scanf("%lld", &x);
            double sinx = sin((double)x), cosx = cos((double)x);//为了减少sin、cos计算,只算一遍,然后把参数传过去
            change(1, 1, n, left, right, x, sinx, cosx);
        }
        else
            printf("%.1f\n", query(1, 1, n, left, right));//一开始写的%.1lf后来改成的%.1f
    }
    return 0;
}
2021/1/15 16:14
加载中...