P3960 列队
Posted sfwr-you
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3960 列队相关的知识,希望对你有一定的参考价值。
————————————————————————————————————————————————————————-
依然是部分分练习,学习了treap后再来做
没想到因为longlong搞死,感觉自己好有毅力
一开始想到了50pt中q很小,第一反应写vector维护,结果写了一半弄晕了,想从题解中找找vector的操作结果看到了50分做法,我好菜
虽然感觉treap的希望很小,但考前练练也说不定
————————————————————————————————————————————————————————
#include<bits/stdc++.h> using namespace std; const int inf=0x7fffffff; const int bow=300100*3; #define ll long long ll num[510][bow/3]; ll last[bow*5],flg[bow*5],n,m,a,b; ll t,root,tot; ll dat[bow],val[bow],l[bow],r[bow],size[bow],cnt[bow]; void update(ll x)size[x]=size[l[x]]+size[r[x]]+cnt[x]; ll cte(ll c)val[++tot]=c;dat[tot]=rand();cnt[tot]=size[tot]=1;return tot; void build()cte(-inf);cte(inf);root=1;r[1]=2;update(root); void zig(ll &p)ll q=l[p];l[p]=r[q];r[q]=p;p=q;update(r[p]);update(p); void zag(ll &p)ll q=r[p];r[p]=l[q];l[q]=p;p=q;update(l[p]);update(p); void insert(ll &p,int c) if(p==0)p=cte(c);return; if(val[p]==c)cnt[p]++;update(p);return; if(c<val[p])insert(l[p],c);if(dat[p]<dat[l[p]])zig(p); else insert(r[p],c);if(dat[p]<dat[r[p]])zag(p); update(p); void remove(ll &p,int c) if(p==0)return; if(val[p]==c) if(cnt[p]>1)cnt[p]--;update(p);return; if(l[p]||r[p]) if(r[p]==0||dat[r[p]]<dat[l[p]])zig(p),remove(r[p],c); else zag(p),remove(l[p],c); update(p); else p=0; return; c<val[p]?remove(l[p],c):remove(r[p],c); update(p); ll gvbr(ll p,ll rk) if(p==0)return inf; if(size[l[p]]>=rk)return gvbr(l[p],rk); if(size[l[p]]+cnt[p]>=rk)return val[p]; return gvbr(r[p],rk-cnt[p]-size[l[p]]); int main() cin>>n>>m>>t; for(int i=1;i<=n;i++)last[i]=i*m; if(t<=500) int maxl=0; while(t--) long long int nc; cin>>a>>b; if(!flg[a])maxl++;flg[a]=maxl;for(int i=1;i<m;i++)num[maxl][i]=(a-1)*m+i; int line=flg[a]; if(b!=m) nc=num[line][b]; for(int i=b;i<m-1;i++)num[line][i]=num[line][i+1]; num[line][m-1]=last[a]; else nc=last[a]; for(int i=a;i<n;i++)last[i]=last[i+1];last[n]=nc; cout<<nc<<endl; else build(); for(int i=1;i<=m;i++)insert(root,i);flg[i]=i; ll tan=m,pos=1,tail=n; while(t--) scanf("%d%d",&a,&b); ll nc=gvbr(root,b+1); remove(root,nc); nc=flg[nc]; tan++;tail++;last[tail]=nc; pos++;flg[tan]=last[pos]; insert(root,tan); printf("%lld\\n",nc);
以上是关于P3960 列队的主要内容,如果未能解决你的问题,请参考以下文章