很简单嗯,我们离散后直接上主席树维护前缀和就行,嗯很简单,然后惊人的MLE了= =
然后找了一个别人过的程序写了一个对拍,然后睡午觉去了
起来了发现并没有挂掉,只是一交就MLE
那么我们有没有什么优化的方法呢?
显然是有的,观察下题目,发现题目中M的范围小于N,而且小了很多!这明显不正常,正常来说操作的个数应该是和N是同阶的,甚至更大才对
再观察下内存使用,发现都是最开始那些初始值占的内存超多
显然我们也并没有必要把这些东西插入到树状数组里
单独把初值建成一坨主席树然后就可以了对吧
查询的时候分开查询下就行啦
空间一下子就从nlognlogn变成了mlognlogn+nlogn,稍微卡卡空间就过了
AC时空间是31916,题库给的是32M= =
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<ctime> #define LL long long #define DB double #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define efo(i,x) for(int i=last[x];i!=0;i=e[i].next) using namespace std; inline LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } #define N 50005 #define M 10005 #define B 50 struct question{ int l,r,k,id; char flag; }Q[M*2]; int a[N*2],hash[N*2],nm; int root[N*2],sz; int sum[N*B],ls[N*B],rs[N*B]; int L[N],R[N]; int num[N*2],tot; int n,m; int lowbit(int x){ return x&(-x); } int find(int x){ int l=1,r=nm,ret; while(l<=r){ int ret=(l+r)>>1; if(hash[ret]==x)return ret; if(hash[ret]<x)l=ret+1; else r=ret-1; } } void updata(int last,int l,int r,int &rt,int val,int ch){ rt=++sz; sum[rt]=sum[last]+ch; ls[rt]=ls[last];rs[rt]=rs[last]; if(l==r)return; int mid=(l+r)>>1; if(val<=mid)updata(ls[last],l,mid,ls[rt],val,ch); else updata(rs[last],mid+1,r,rs[rt],val,ch); } int Query(int k,int l,int r,int ll,int rr){ if(l==r)return l; int suml=0,sumr=0; fo(i,1,ll)suml+=sum[ls[L[i]]]; fo(i,1,rr)sumr+=sum[ls[R[i]]]; int mid=(l+r)>>1; if(sumr-suml>=k){ fo(i,1,ll)L[i]=ls[L[i]]; fo(i,1,rr)R[i]=ls[R[i]]; return Query(k,l,mid,ll,rr); }else{ fo(i,1,ll)L[i]=rs[L[i]]; fo(i,1,rr)R[i]=rs[R[i]]; return Query(k-(sumr-suml),mid+1,r,ll,rr); } } void init_clr(){ memset(Q,0,sizeof(Q)); memset(a,0,sizeof(a)); memset(num,0,sizeof(num)); memset(sum,0,sizeof(sum)); memset(ls,0,sizeof(ls)); memset(rs,0,sizeof(rs)); memset(root,0,sizeof(root)); memset(hash,0,sizeof(hash)); tot=0;nm=0;sz=0;n=m=0; } char getNxt(){ char s=getchar(); while(s!='Q'&&s!='C')s=getchar(); return s; } void init_read(){ n=read(),m=read(); fo(i,1,n)a[i]=read(),num[++tot]=a[i]; fo(i,1,m){ char ch=getNxt(); if(ch=='Q'){ Q[i].flag=ch; Q[i].l=read(),Q[i].r=read(); Q[i].k=read(); }else{ Q[i].flag=ch; Q[i].l=read(); Q[i].k=read(); num[++tot]=Q[i].k; } } } void LS(){ sort(num+1,num+tot+1); hash[++nm]=num[1]; fo(i,2,tot){ if(num[i]!=num[i-1]){ hash[++nm]=num[i]; } } } void build(int &k,int l,int r,int val){ sum[++sz]=sum[k]+1; ls[sz]=ls[k];rs[sz]=rs[k]; k=sz; if(l==r)return; int mid=(l+r)>>1; if(val<=mid)build(ls[k],l,mid,val); else build(rs[k],mid+1,r,val); } void buildtree(){ fo(i,1,n){ root[i+n]=root[i+n-1]; int x=find(a[i]); build(root[i+n],1,nm,x); } } void work(){ fo(i,1,m){ // cerr<<i<<' '<<m<<' '<<(char)Q[i].flag<<' '<<Q[i].l<<' '<<Q[i].r<<' '<<Q[i].k<<endl; if(Q[i].flag!='Q'&&Q[i].flag!='C'){ cerr<<i<<endl; return; } if(Q[i].flag=='Q'){ Q[i].l--; int a=0,b=0; L[++a]=root[Q[i].l?Q[i].l+n:0]; R[++b]=root[Q[i].r+n]; for(int j=Q[i].l;j>0;j-=lowbit(j)){ L[++a]=root[j]; } for(int j=Q[i].r;j>0;j-=lowbit(j)){ R[++b]=root[j]; } int temp=Query(Q[i].k,1,nm,a,b); int ans=hash[temp]; printf("%d\n",ans); }else{ int val=find(a[Q[i].l]); for(int j=Q[i].l;j<=n;j+=lowbit(j)){ updata(root[j],1,nm,root[j],val,-1); } a[Q[i].l]=Q[i].k; val=find(Q[i].k); for(int j=Q[i].l;j<=n;j+=lowbit(j)){ updata(root[j],1,nm,root[j],val,1); } } } } int main(){ // freopen("data.in","r",stdin); // freopen("data.out","w",stdout); int T=read(); while(T--){ init_clr(); init_read(); // cout<<"finishread"<<endl; LS(); // cout<<"finishLS"<<endl; buildtree(); // cout<<"finishbuild"<<endl; work(); // cout<<"finishwork"<<endl; } return 0; }
卡了半天常数和空间的最终版,狗带了120ms还是不在第一版
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long #define DB double #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define efo(i,x) for(int i=last[x];i!=0;i=e[i].next) using namespace std; inline LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } #define ENT putchar('\n') inline void write(LL x) { if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; int len=0,buf[20];while(x)buf[len++]=x%10,x/=10; for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; } inline void writeln(LL x){write(x);ENT;} #define N 50005 #define M 10005 #define B 43 struct question{ int l,r,k; char flag; }Q[M]; int a[N],hash[N*2],nm; int root[N*2],sz; int sum[N*B],ls[N*B],rs[N*B]; int L[30],R[30]; int num[N*2],tot; int n,m; inline int lowbit(int x){ return x&(-x); } int l,r,ret; inline int find(int x){ l=1,r=nm; while(l<=r){ ret=(l+r)>>1; if(hash[ret]==x)return ret; if(hash[ret]<x)l=ret+1; else r=ret-1; } } int mid; void updata(int last,int l,int r,int &rt,int val,int ch){ rt=++sz; sum[rt]=sum[last]+ch; ls[rt]=ls[last];rs[rt]=rs[last]; if(l==r)return; mid=(l+r)>>1; if(val<=mid)updata(ls[last],l,mid,ls[rt],val,ch); else updata(rs[last],mid+1,r,rs[rt],val,ch); } int suml,sumr; int Query(int k,int l,int r,int ll,int rr){ if(l==r)return l; suml=0,sumr=0; fo(i,1,ll)suml+=sum[ls[L[i]]]; fo(i,1,rr)sumr+=sum[ls[R[i]]]; mid=(l+r)>>1; if(sumr-suml>=k){ fo(i,1,ll)L[i]=ls[L[i]]; fo(i,1,rr)R[i]=ls[R[i]]; return Query(k,l,mid,ll,rr); }else{ fo(i,1,ll)L[i]=rs[L[i]]; fo(i,1,rr)R[i]=rs[R[i]]; return Query(k-(sumr-suml),mid+1,r,ll,rr); } } inline void init_clr(){ // memset(Q,0,sizeof(Q)); // memset(a,0,sizeof(a)); // memset(num,0,sizeof(num)); // memset(sum,0,sizeof(sum)); // memset(ls,0,sizeof(ls)); // memset(rs,0,sizeof(rs)); memset(root,0,sizeof(root)); // memset(hash,0,sizeof(hash)); tot=0;nm=0;sz=0;n=m=0; } inline char getNxt(){ char s=getchar(); while(s!='Q'&&s!='C')s=getchar(); return s; } inline void init_read(){ n=read(),m=read(); fo(i,1,n)a[i]=read(),num[++tot]=a[i]; fo(i,1,m){ char ch=getNxt(); if(ch=='Q'){ Q[i].flag=ch; Q[i].l=read(),Q[i].r=read(); Q[i].k=read(); }else{ Q[i].flag=ch; Q[i].l=read(); Q[i].k=read(); num[++tot]=Q[i].k; } } } inline void LS(){ sort(num+1,num+tot+1); hash[++nm]=num[1]; fo(i,2,tot){ if(num[i]!=num[i-1]){ hash[++nm]=num[i]; } } } void build(int &k,int l,int r,int val){ sum[++sz]=sum[k]+1; ls[sz]=ls[k];rs[sz]=rs[k]; k=sz; if(l==r)return; mid=(l+r)>>1; if(val<=mid)build(ls[k],l,mid,val); else build(rs[k],mid+1,r,val); } inline void buildtree(){ fo(i,1,n){ root[i+n]=root[i+n-1]; int x=find(a[i]); build(root[i+n],1,nm,x); } } int ans,z,b,val; inline void work(){ fo(i,1,m){ if(Q[i].flag=='Q'){ Q[i].l--; z=0,b=0; L[++z]=root[Q[i].l?Q[i].l+n:0]; R[++b]=root[Q[i].r+n]; for(int j=Q[i].l;j>0;j-=lowbit(j)){ L[++z]=root[j]; } for(int j=Q[i].r;j>0;j-=lowbit(j)){ R[++b]=root[j]; } ans=hash[Query(Q[i].k,1,nm,z,b)]; writeln(ans); }else{ val=find(a[Q[i].l]); for(int j=Q[i].l;j<=n;j+=lowbit(j)){ updata(root[j],1,nm,root[j],val,-1); } a[Q[i].l]=Q[i].k; val=find(Q[i].k); for(int j=Q[i].l;j<=n;j+=lowbit(j)){ updata(root[j],1,nm,root[j],val,1); } } } } int main(){ freopen("data.in","r",stdin); freopen("data.out","w",stdout); int T=read(); while(T--){ init_clr(); init_read(); // cout<<"finishread"<<endl; LS(); // cout<<"finishLS"<<endl; buildtree(); // cout<<"finishbuild"<<endl; work(); // cout<<"finishwork"<<endl; } return 0; }