[TJOI2019]甲苯先生的滚榜——非旋转treap
作者:互联网
题目链接:
要求维护一个二维权值的集合并支持单点修改,用平衡树维护即可。
因为$n\le 10^6$但$m\le 10^5$,所以最多只有$10^5$个人被操作。
记录每个人的二维权值,只维护被操作过的人权值的平衡树即可。
如果一开始将$10^6$个人都建出来会$TLE$。
#include<set> #include<map> #include<queue> #include<cmath> #include<stack> #include<vector> #include<bitset> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef unsigned int ui; int ls[100010]; int rs[100010]; int r[100010]; int v[100010]; int t[100010]; int size[100010]; int cnt; int m,T; ui seed; int x,y; int a,b,c; ui last=7; ui n; int ac[1000010]; int tim[1000010]; int root; ui randNum(ui& seed,ui last,const ui m) { seed=seed*17+last; return seed%m+1; } inline void init() { cnt=root=0; memset(ac,0,sizeof(ac)); memset(tim,0,sizeof(tim)); } inline int build(int val) { int rt=++cnt; r[rt]=rand(); v[rt]=1; t[rt]=val; size[rt]=1; ls[rt]=rs[rt]=0; return rt; } inline void pushup(int rt) { size[rt]=size[ls[rt]]+size[rs[rt]]+1; } inline int merge(int x,int y) { if(!x||!y) { return x+y; } if(r[x]<r[y]) { rs[x]=merge(rs[x],y); pushup(x); return x; } else { ls[y]=merge(x,ls[y]); pushup(y); return y; } } inline void split(int rt,int &x,int &y,int ac,int tim) { if(!rt) { x=y=0; return ; } if(v[rt]<ac||(v[rt]==ac&&t[rt]>=tim)) { y=rt; split(ls[rt],x,ls[y],ac,tim); pushup(y); } else { x=rt; split(rs[rt],rs[x],y,ac,tim); pushup(x); } } inline void split2(int rt,int &x,int &y,int k) { if(!rt) { x=y=0; return ; } if(size[ls[rt]]>=k) { y=rt; split2(ls[rt],x,ls[y],k); pushup(y); } else { x=rt; split2(rs[rt],rs[x],y,k-size[ls[rt]]-1); pushup(x); } } inline void solve() { scanf("%u%d%u",&n,&m,&seed); for(int i=1;i<=m;i++) { x=randNum(seed,last,n); y=randNum(seed,last,n); if(!ac[x]) { ac[x]++; tim[x]+=y; int now=build(tim[x]); split(root,a,b,ac[x],tim[x]); root=merge(a,merge(now,b)); } else { split(root,a,b,ac[x],tim[x]); split2(b,b,c,1); v[b]++; t[b]+=y; root=merge(a,c); split(root,a,c,v[b],t[b]); root=merge(merge(a,b),c); ac[x]++; tim[x]+=y; } split(root,a,b,ac[x],tim[x]); last=size[a]; printf("%d\n",last); root=merge(a,b); } } int main() { scanf("%d",&T); while(T--) { init(); solve(); } }
标签:rt,include,int,treap,ui,ls,TJOI2019,甲苯,size 来源: https://www.cnblogs.com/Khada-Jhin/p/10826676.html