卡常的kdtree……将标识符看为y轴上的对应的点,然后直接在kdtree上标记就可以了
被卡常了很悲伤……以下代码目前没有卡常卡过去先放着吧
------
UPD 2016.9.29
找管理员要来了数据……本机是9s不到(开O2)17s(不开O2),到了bzoj上就是20s+……
我从14s+卡常卡到9s不到容易吗我……
就不能放宽点时限么……
没错我现在还是TLE
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define Add(x,y) (x=(x+y)%P) #define Mul(x,y) (x=x*y%P) const int N=50005; const long long P=536870912ll; int n,m,sort_tag,root,l,r; long long x,y; template<typename T>inline void Read(T &x){ static char ch; while((ch=getchar())<'0' || ch>'9'); x=ch-'0'; while((ch=getchar())>='0' && ch<='9')x=(x<<3)+(x<<1)+ch-'0'; } struct KDTree{ int d[2],mn[2],mx[2],ch[2]; long long add,mul,sum,v,siz; KDTree(){mul=siz=1;sum=v=add=0;} friend inline bool operator<(const KDTree &A,const KDTree &B){return A.d[sort_tag]<B.d[sort_tag];} }tree[N]; inline void Pushdown(int rt){ if(tree[rt].mul!=1){ if(tree[rt].ch[0]){ Mul(tree[tree[rt].ch[0]].add,tree[rt].mul); Mul(tree[tree[rt].ch[0]].sum,tree[rt].mul); Mul(tree[tree[rt].ch[0]].mul,tree[rt].mul); Mul(tree[tree[rt].ch[0]].v,tree[rt].mul); } if(tree[rt].ch[1]){ Mul(tree[tree[rt].ch[1]].add,tree[rt].mul); Mul(tree[tree[rt].ch[1]].sum,tree[rt].mul); Mul(tree[tree[rt].ch[1]].mul,tree[rt].mul); Mul(tree[tree[rt].ch[1]].v,tree[rt].mul); } tree[rt].mul=1; } if(tree[rt].add){ if(tree[rt].ch[0]){ Add(tree[tree[rt].ch[0]].add,tree[rt].add); Add(tree[tree[rt].ch[0]].sum,tree[rt].add*tree[tree[rt].ch[0]].siz%P); Add(tree[tree[rt].ch[0]].v,tree[rt].add); } if(tree[rt].ch[1]){ Add(tree[tree[rt].ch[1]].add,tree[rt].add); Add(tree[tree[rt].ch[1]].sum,tree[rt].add*tree[tree[rt].ch[1]].siz%P); Add(tree[tree[rt].ch[1]].v,tree[rt].add); } tree[rt].add=0; } } inline void Pushup_(int rt){ tree[rt].sum=tree[rt].siz=0; if(tree[rt].ch[0]){ tree[rt].mx[0]=max(tree[rt].mx[0],tree[tree[rt].ch[0]].mx[0]); tree[rt].mx[1]=max(tree[rt].mx[1],tree[tree[rt].ch[0]].mx[1]); tree[rt].mn[0]=min(tree[rt].mn[0],tree[tree[rt].ch[0]].mn[0]); tree[rt].mn[1]=min(tree[rt].mn[1],tree[tree[rt].ch[0]].mn[1]); Add(tree[rt].siz,tree[tree[rt].ch[0]].siz); Add(tree[rt].sum,tree[tree[rt].ch[0]].sum); } if(tree[rt].ch[1]){ tree[rt].mx[0]=max(tree[rt].mx[0],tree[tree[rt].ch[1]].mx[0]); tree[rt].mx[1]=max(tree[rt].mx[1],tree[tree[rt].ch[1]].mx[1]); tree[rt].mn[0]=min(tree[rt].mn[0],tree[tree[rt].ch[1]].mn[0]); tree[rt].mn[1]=min(tree[rt].mn[1],tree[tree[rt].ch[1]].mn[1]); Add(tree[rt].siz,tree[tree[rt].ch[1]].siz); Add(tree[rt].sum,tree[tree[rt].ch[1]].sum); } Add(tree[rt].sum,tree[rt].v); Add(tree[rt].siz,1ll); } int Build(int l,int r,int t){ int mid=l+r>>1; sort_tag=t; nth_element(tree+l,tree+mid,tree+r+1); tree[mid].mn[0]=tree[mid].mx[0]=tree[mid].d[0]; tree[mid].mn[1]=tree[mid].mx[1]=tree[mid].d[1]; if(l<mid)tree[mid].ch[0]=Build(l,mid-1,t^1); if(r>mid)tree[mid].ch[1]=Build(mid+1,r,t^1); Pushup_(mid); return mid; } void Addv(int rt,int tag){ if(!rt)return; Pushdown(rt); if(!tag){ if(l<=tree[rt].mn[tag] && tree[rt].mx[tag]<=r){ Mul(tree[rt].sum,x); Add(tree[rt].sum,y*tree[rt].siz%P); Mul(tree[rt].mul,x); Mul(tree[rt].add,x); Add(tree[rt].add,y); Mul(tree[rt].v,x); Add(tree[rt].v,y); return; } if(l<=tree[rt].d[tag] && tree[rt].d[tag]<=r){ long long vx=tree[rt].v; Mul(tree[rt].v,x); Add(tree[rt].v,y); Add(tree[rt].sum,tree[rt].v-vx); } int mid=tree[rt].d[tag]; if(l<mid)Addv(tree[rt].ch[0],tag^1); if(r>mid)Addv(tree[rt].ch[1],tag^1); tree[rt].sum=(tree[tree[rt].ch[0]].sum+tree[tree[rt].ch[1]].sum+tree[rt].v)%P; } else { if(l<=tree[rt].mn[!tag] && tree[rt].mx[!tag]<=r){ Mul(tree[rt].sum,x); Add(tree[rt].sum,y*tree[rt].siz%P); Mul(tree[rt].mul,x); Mul(tree[rt].add,x); Add(tree[rt].add,y); Mul(tree[rt].v,x); Add(tree[rt].v,y); return; } if(l<=tree[rt].d[!tag] && tree[rt].d[!tag]<=r){ long long vx=tree[rt].v; Mul(tree[rt].v,x); Add(tree[rt].v,y); Add(tree[rt].sum,tree[rt].v-vx); } if(l<=tree[rt].mx[!tag])Addv(tree[rt].ch[0],tag^1); if(r>=tree[rt].mn[!tag])Addv(tree[rt].ch[1],tag^1); tree[rt].sum=(tree[tree[rt].ch[0]].sum+tree[tree[rt].ch[1]].sum+tree[rt].v)%P; } } void Addv2(int rt,int tag){ if(!rt)return; Pushdown(rt); if(tag){ if(l<=tree[rt].mn[tag] && tree[rt].mx[tag]<=r){ Mul(tree[rt].sum,x); Add(tree[rt].sum,y*tree[rt].siz%P); Mul(tree[rt].mul,x); Mul(tree[rt].add,x); Add(tree[rt].add,y); Mul(tree[rt].v,x); Add(tree[rt].v,y); return; } if(l<=tree[rt].d[tag] && tree[rt].d[tag]<=r){ long long vx=tree[rt].v; Mul(tree[rt].v,x); Add(tree[rt].v,y); Add(tree[rt].sum,tree[rt].v-vx); } int mid=tree[rt].d[tag]; if(l<mid)Addv2(tree[rt].ch[0],tag^1); if(r>mid)Addv2(tree[rt].ch[1],tag^1); tree[rt].sum=(tree[tree[rt].ch[0]].sum+tree[tree[rt].ch[1]].sum+tree[rt].v)%P; } else { if(l<=tree[rt].mn[!tag] && tree[rt].mx[!tag]<=r){ Mul(tree[rt].sum,x); Add(tree[rt].sum,y*tree[rt].siz%P); Mul(tree[rt].mul,x); Mul(tree[rt].add,x); Add(tree[rt].add,y); Mul(tree[rt].v,x); Add(tree[rt].v,y); return; } if(l<=tree[rt].d[!tag] && tree[rt].d[!tag]<=r){ long long vx=tree[rt].v; Mul(tree[rt].v,x); Add(tree[rt].v,y); Add(tree[rt].sum,tree[rt].v-vx); } if(l<=tree[rt].mx[!tag])Addv2(tree[rt].ch[0],tag^1); if(r>=tree[rt].mn[!tag])Addv2(tree[rt].ch[1],tag^1); tree[rt].sum=(tree[tree[rt].ch[0]].sum+tree[tree[rt].ch[1]].sum+tree[rt].v)%P; } } long long Sum(int rt,int tag){ if(!rt)return 0ll; long long ans=0ll; Pushdown(rt); if(!tag){ if(l<=tree[rt].mn[tag] && tree[rt].mx[tag]<=r)return tree[rt].sum; if(l<=tree[rt].d[tag] && tree[rt].d[tag]<=r)ans=(ans+tree[rt].v)%P; int mid=tree[rt].d[tag]; if(l<mid)ans=(ans+Sum(tree[rt].ch[0],!tag))%P; if(r>mid)ans=(ans+Sum(tree[rt].ch[1],!tag))%P; return ans; } else { if(l<=tree[rt].mn[!tag] && tree[rt].mx[!tag]<=r)return tree[rt].sum; if(l<=tree[rt].d[!tag] && tree[rt].d[!tag]<=r)ans=(ans+tree[rt].v)%P; if(l<=tree[rt].mx[!tag])ans=(ans+Sum(tree[rt].ch[0],!tag))%P; if(r>=tree[rt].mn[!tag])ans=(ans+Sum(tree[rt].ch[1],!tag))%P; return ans; } } long long Sum2(int rt,int tag){ if(!rt)return 0ll; long long ans=0ll; Pushdown(rt); if(tag){ if(l<=tree[rt].mn[tag] && tree[rt].mx[tag]<=r)return tree[rt].sum; if(l<=tree[rt].d[tag] && tree[rt].d[tag]<=r)ans=(ans+tree[rt].v)%P; int mid=tree[rt].d[tag]; if(l<mid)ans=(ans+Sum2(tree[rt].ch[0],!tag))%P; if(r>mid)ans=(ans+Sum2(tree[rt].ch[1],!tag))%P; return ans; } else { if(l<=tree[rt].mn[!tag] && tree[rt].mx[!tag]<=r)return tree[rt].sum; if(l<=tree[rt].d[!tag] && tree[rt].d[!tag]<=r)ans=(ans+tree[rt].v)%P; if(l<=tree[rt].mx[!tag])ans=(ans+Sum2(tree[rt].ch[0],!tag))%P; if(r>=tree[rt].mn[!tag])ans=(ans+Sum2(tree[rt].ch[1],!tag))%P; return ans; } } int main(){ freopen("4303.in","r",stdin); freopen("4303.out","w",stdout); Read(n);Read(m); for(register int i=1;i<=n;i++){Read(tree[i].d[1]);tree[i].d[0]=i;} root=Build(1,n,1); while(m--){ static int opt; Read(opt);Read(l);Read(r); if(opt==0){Read(x);Read(y);Addv(root,1);} if(opt==1){Read(x);Read(y);Addv2(root,1);} if(opt==2){printf("%lld\n",Sum(root,1));} if(opt==3){printf("%lld\n",Sum2(root,1));} } return 0; }