记录,维护的sin和cos,普通线段树版自测是对的,但是常数大,所以换的zkw,然后好像写挂了,Y判N和N判Y的都有
#include<iostream>
#include<cstdio>
#include<cmath>
#define double long double
using namespace std;
int inline read()
{
int ans=0,f=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(isdigit(ch))
{
ans=ans*10+ch-'0';
ch=getchar();
}
return ans*f;
}
const int N=1e6+5;
const double eps=1e-4;
struct tree
{
int maxx,minn,sum;
double si,co;
tree operator +(const tree &p)
{
tree ans;
ans.maxx=max(maxx,p.maxx);
ans.minn=min(minn,p.minn);
ans.sum=sum+p.sum;
ans.si=si+p.si;
ans.co=co+p.co;
return ans;
}
}t[8*N];
int n,m,M;
void build(int n)
{
for(M=1;M<n;M<<=1) ;
for(int i=M+1;i<=M+n;i++) t[i].maxx=t[i].minn=t[i].sum=read(),t[i].si=sin(t[i].maxx),t[i].co=cos(t[i].maxx);
for(int i=M-1;i;i--) t[i]=t[i<<1]+t[i<<1|1];
}
void change(int x,int v)
{
x+=M;
t[x].maxx=t[x].minn=t[x].sum=v,t[x].co=cos(v),t[x].si=sin(v);
while(x) t[x>>=1]=t[x<<1]+t[x<<1|1];
}
tree ask(int l,int r)
{
tree ans=(tree){0,1e9,0,0.0,0.0};
for(int s=l+M-1,tt=r+M+1;s^tt^1;s>>=1,tt>>=1)
{
if(~s&1) ans=ans+t[s^1];
if(tt&1) ans=ans+t[tt^1];
}
return ans;
}
double f(double x)
{
if(x<0) return -x;
return x;
}
signed main()
{
n=read();m=read();
build(n);
for(int i=1;i<=m;i++)
{
int op=read();
if(op==0)
{
int x=read(),y=read();
change(x,y);
}
else
{
int l1=read(),r1=read(),l2=read(),r2=read();
tree ans1=ask(l1,r1),ans2=ask(l2,r2);
if(ans1.maxx<ans2.maxx) swap(ans1,ans2);
int t=ans1.maxx-ans2.maxx;
if(t!=ans1.minn-ans2.minn||t*(r2-l2+1)!=ans1.sum-ans2.sum)
{
puts("NO");
continue;
}
double sint=sin(t),cost=cos(t);
double _1=ans2.si*cost+ans2.co*sint;
double _2=ans2.co*cost-ans2.si*sint;
if(f(_1-ans1.si)<eps&&f(_2-ans1.co)<eps) puts("YES");
else puts("NO");
}
}
return 0;
}