很简单嗯,我们离散后直接上主席树维护前缀和就行,嗯很简单,然后惊人的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;
}