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 列队的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P3960 列队(动态开点线段树)

P3960 列队

P3960 列队

[NOIP2017]列队

[luogu P3960] [noip2017 d2t3] 队列

NOIP2017 列队