先是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;
}