【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题
达神题解传送门:http://blog.csdn.net/dad3zz/article/details/50638360
说一下我对这个模板的理解:
看到这个方法很容易不知所措,因为动态K值需要套树状数组,而我一开始根本不知道该怎么套,,
学习吧,,,
然后我自己脑补如果不套会如何?后来想到是查询O(logn),修改是O(nlogn),很明显修改的复杂度太大了,为了降低修改的复杂度,我们只得套上树状数组来维护前缀和使它的n的复杂度降低为logn,从而修改的复杂度变为O(log2n)。但因为我们套了树状数组,所以查询的复杂度也不得不上升到O(log2n),但从整体上看来这些牺牲是值得的,总复杂度最终是O(nlog2n)。
这些都太简单了是吧,,果然我太傻,,
比较的时候和普通的主席树不同,不再是两个做差了,而是把树状数组中的节点放到两个池子里做差,我的code里是L和R两个池子,,
至于为什么要离线,我思考了很久,,,问过达神,,,并不理解,,,继续思考,,,后来明白是为了找到所有序列中出现的数的最大值,这样才能建树啊,,,然后得出结论:我太傻以至于马上就要滚粗了,,,TAT
最后向iwtwiioi寻求帮助,知道自己错误的原因是数组开的太小了,,
达神也帮我开大过,不过貌似太大炸了导致每次都是TLE或WA,,
还是得注意细节啊,这道题一个晚上才写出了模板,我果然太弱了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #include<cstdio> #include<algorithm> #define lowbit(x) (x&-x) #define read(x) x=getint() #define for1(i,a,n) for(int i=(a);i<=(n);++i) using namespace std; const int N=10010; inline const int getint(){ char c= getchar (); int k=1,r=0; for (;c< '0' ||c> '9' ;c= getchar ()) if (c== '-' )k=-1; for (;c>= '0' &&c<= '9' ;c= getchar ())r=r*10+c- '0' ; return k*r;} struct node{ int l,r,s;}T[N*300]; int n,m,cl,cr,tot=0,num=0,cnt=0,ans[N<<1],root[N],a[N],L[N],R[N],QL[N],QR[N],K[N]; inline void update( const int &l, const int &r, int &pos, const int &k, const int &sz){ T[++tot]=T[pos]; pos=tot; T[pos].s+=sz; if (l==r) return ; int mid=(l+r)>>1; if (k<=mid) update(l,mid,T[pos].l,k,sz); else update(mid+1,r,T[pos].r,k,sz); } inline void addd( int x, const int &k, const int &sz){ for (;x<=n;x+=lowbit(x)) update(1,num,root[x],k,sz);} inline int query( const int &l, const int &r, const int &k){ if (l==r) return l; int suml=0,sumr=0; for1(i,1,cl) suml+=T[T[L[i]].l].s; for1(i,1,cr) sumr+=T[T[R[i]].l].s; int mid=(l+r)>>1; if (k<=sumr-suml){ for1(i,1,cl) L[i]=T[L[i]].l; for1(i,1,cr) R[i]=T[R[i]].l; return query(l,mid,k); } else { for1(i,1,cl) L[i]=T[L[i]].r; for1(i,1,cr) R[i]=T[R[i]].r; return query(mid+1,r,k-sumr+suml); } } inline int getans( int l, int r, const int &k){ for (cl=0;l>0;l-=lowbit(l)) L[++cl]=root[l]; for (cr=0;r>0;r-=lowbit(r)) R[++cr]=root[r]; return query(1,num,k); } int main(){ read(n); read(m); char c; for1(i,1,n) read(a[i]),ans[++cnt]=a[i]; for1(i,1,m){ for (c= getchar ();c< 'A' ||c> 'Z' ;c= getchar ()); read(QL[i]); read(QR[i]); if (c== 'Q' ) read(K[i]); else ans[++cnt]=QR[i]; }sort(ans+1,ans+cnt+1); ans[cnt+1]=1E9+10; for1(i,1,cnt) if (ans[i]!=ans[i+1]) ans[++num]=ans[i]; for1(i,1,n) a[i]=lower_bound(ans+1,ans+num+1,a[i])-ans; for1(i,1,n) addd(i,a[i],1); for1(i,1,m){ if (K[i]) printf ( "%d\n" ,ans[getans(QL[i]-1,QR[i],K[i])]); else { addd(QL[i],a[QL[i]],-1); a[QL[i]]=lower_bound(ans+1,ans+num+1,QR[i])-ans; addd(QL[i],a[QL[i]],1); } } return 0; } |
然后就可以了。这是DaD3zZ几年前就随手虐的东西,本蒟蒻还得继续努力呀~~~
NOI 2017 Bless All
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)