中考完练练手,本来想回顾一下线段树,结果这么显然的题目依然 bug 多多,全 WA。
而且 debug 能力严重退化。希望是些 sb 错误。
欢迎各路神仙 D 这个 xxs。
码风应该还行,变量名通俗易懂,不打注释应该也没有障碍阅读了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define mid ((tree[cur].l+tree[cur].r)>>1)
#define lson (cur<<1)
#define rson (cur<<1|1)
using namespace std;
typedef const int cint;
cint MAXN=2e5+5;
int n,m;
int a[MAXN];
class segment_tree
{
private:
struct node
{
int l,r;
long long tag;
long double sinv,cosv;
}tree[MAXN*4];
inline void pushup(cint cur)
{
tree[cur].sinv=tree[lson].sinv+tree[rson].sinv;
tree[cur].cosv=tree[lson].cosv+tree[rson].cosv;
}
inline void calc(cint cur,cint t)
{
const long double sinx=sin(t),cosx=cos(t);
const long double siny=tree[cur].sinv,cosy=tree[cur].cosv;
tree[cur].sinv=siny*cosx+cosy*sinx;
tree[cur].cosv=cosy*cosx-siny*sinx;
}
inline void pushdown(cint cur)
{
if(tree[cur].tag==0)
return;
calc(lson,tree[cur].tag);
calc(rson,tree[cur].tag);
tree[lson].tag+=tree[cur].tag;
tree[rson].tag+=tree[cur].tag;
tree[cur].tag=0;
}
public:
void build(cint cur,cint l,cint r)
{
tree[cur].l=l;tree[cur].r=r;
if(l==r)
{
tree[cur].sinv=sin(a[l]);
tree[cur].cosv=cos(a[l]);
return;
}
build(lson,l,mid);
build(rson,mid+1,r);
pushup(cur);
}
void modify(cint cur,cint l,cint r,cint val)
{
if(l<=tree[cur].l && tree[cur].r<=r)
{
calc(cur,val);
tree[cur].tag+=val;
return;
}
pushdown(cur);
if(l<=mid) modify(lson,l,r,val);
if(mid<r) modify(rson,l,r,val);
pushup(cur);
}
long double query(cint cur,cint l,cint r)
{
if(l<=tree[cur].l && tree[cur].r<=r)
return tree[cur].sinv;
long double res=0;
pushdown(cur);
if(l<=mid) res+=query(lson,l,r);
if(mid<r) res+=query(rson,l,r);
return res;
}
}t;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cin>>m;
t.build(1,1,n);
while(m--)
{
int opt,l,r;cin>>opt>>l>>r;
if(opt==1)
{
int v;cin>>v;
t.modify(1,l,r,v);
}
if(opt==2)
printf("%.1Lf\n",t.query(1,l,r));
}
return 0;
}