提交时间:2024-11-12 21:42:38
运行 ID: 34723
#include<bits/stdc++.h> using namespace std; #define ls pos<<1 #define rs pos<<1|1 #define int long long const int N=1e5+10,M=1e9+7; int n,m,a[N],ans; //tg0:是否全是0;tg1:是否全是-1;tg2:是否全是1 //lz:区间取相反数的懒标记 struct Tree{int s,pf;bool tg0,tg1,tg2,lz;}t[N<<2]; void swap(bool &a,bool &b){bool f=a;a=b;b=f;} void pushup(int pos){ t[pos].s=(t[ls].s+t[rs].s)%M; t[pos].pf=(t[ls].pf+t[rs].pf)%M; t[pos].tg0=t[ls].tg0&t[rs].tg0; t[pos].tg1=t[ls].tg1&t[rs].tg1; t[pos].tg2=t[ls].tg2&t[rs].tg2; } void pushdown(int pos,int l,int r){ if(!t[pos].lz)return; t[ls].s=-t[ls].s;t[rs].s=-t[rs].s; swap(t[ls].tg1,t[ls].tg2); swap(t[rs].tg1,t[rs].tg2); t[ls].lz^=1;t[rs].lz^=1; t[pos].lz=0; } void build(int pos,int l,int r){ if(l==r){ t[pos].s=a[l];t[pos].pf=(a[l]*a[l])%M; if(a[l]==0)t[pos].tg0=1; if(a[l]==-1)t[pos].tg1=1; if(a[l]==1)t[pos].tg2=1;return; } int mid=(l+r)>>1; build(ls,l,mid);build(rs,mid+1,r); pushup(pos); } int query1(int pos,int l,int r,int ql,int qr){ if(l>=ql&&r<=qr){return t[pos].s;} int mid=(l+r)>>1,res=0; pushdown(pos,l,r); if(ql<=mid)res=(query1(ls,l,mid,ql,qr)+M)%M; if(qr>mid)res=(res+query1(rs,mid+1,r,ql,qr)+M)%M; return (res+M)%M; } int query2(int pos,int l,int r,int ql,int qr){ if(l>=ql&&r<=qr){return t[pos].pf;} int mid=(l+r)>>1,res=0; pushdown(pos,l,r); if(ql<=mid)res=(query2(ls,l,mid,ql,qr)+M)%M; if(qr>mid)res=(res+query2(rs,mid+1,r,ql,qr)+M)%M; return (res+M)%M; } void modify(int pos,int l,int r,int x,int k){ if(l==r){ t[pos].s=k;t[pos].pf=(k*k)%M; if(k==0)t[pos].tg0=1;else t[pos].tg0=0; if(k==-1)t[pos].tg1=1;else t[pos].tg1=0; if(k==1)t[pos].tg2=1;else t[pos].tg2=0; return; } int mid=(l+r)>>1; pushdown(pos,l,r); if(x<=mid)modify(ls,l,mid,x,k); else modify(rs,mid+1,r,x,k); pushup(pos); } void modify1(int pos,int l,int r,int ql,int qr,int k){ if(t[pos].tg0||(t[pos].tg1&&k>0))return; if(l==r){ if(t[pos].s*k>0){t[pos].s/=k;} else { if(t[pos].s%k==0)t[pos].s/=k; else {t[pos].s/=k;t[pos].s--;} } t[pos].pf=t[pos].s*t[pos].s%M; if(t[pos].s==0)t[pos].tg0=1;else t[pos].tg0=0; if(t[pos].s==-1)t[pos].tg1=1;else t[pos].tg1=0; if(t[pos].s==1)t[pos].tg2=1;else t[pos].tg2=0; return; } int mid=(l+r)>>1; pushdown(pos,l,r); if(ql<=mid)modify1(ls,l,mid,ql,qr,k); if(qr>mid)modify1(rs,mid+1,r,ql,qr,k); pushup(pos); } void modify3(int pos,int l,int r,int ql,int qr){ if(l>=ql&&r<=qr){ t[pos].s=-t[pos].s; swap(t[pos].tg1,t[pos].tg2); t[pos].lz^=1; return; } int mid=(l+r)>>1; pushdown(pos,l,r); if(ql<=mid)modify3(ls,l,mid,ql,qr); if(qr>mid)modify3(rs,mid+1,r,ql,qr); pushup(pos); } signed main(){ scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); build(1,1,n); int opt,l,r,p,v; while(m--){ scanf("%lld",&opt); if(opt==1){ scanf("%lld%lld",&l,&r); ans=query1(1,1,n,l,r); printf("%lld\n",ans); } if(opt==2){ scanf("%lld%lld",&l,&r); ans=query2(1,1,n,l,r); printf("%lld\n",ans); } if(opt==3){ scanf("%lld%lld%lld",&l,&r,&p); if(p==1)continue; if(p==-1)modify3(1,1,n,l,r); else modify1(1,1,n,l,r,p); } if(opt==4){ scanf("%lld%lld",&p,&v); modify(1,1,n,p,v); } // for(int i=1;i<=n*2;i++)cout<<t[i].s<<" "; // cout<<endl; } return 0; }