zoukankan      html  css  js  c++  java
  • [NOIP 2017]列队

    题意:维护一个矩阵的左对齐和上对齐,并输出结果。

    思路:

    正解似乎是树状数组??

    可惜并不知道怎么写,我们就可以考虑用平衡树裂点来维护矩阵。

    然后就发现还有动态开点线段树的这种操作...

    后来。。。其实一棵主席树完全可以干爆此题。。。。。。。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    typedef long long ll;
    struct node
    {
        int x,y;
    }a[310000];
    struct tree
    {
        int lc,rc;ll c;
    }tr[6100000];int tail[310000],root[310000];
    int tot=0;int size[6100000];
    void insert(int &now,int l,int r,int k,ll num)
    {
        if(now==0) now=++tot;
        if(l==r)
        {
            tr[now].c=num;
            size[now]=0;
            return ;
        }
        int mid=(l+r)/2;
        if(k<=mid) insert(tr[now].lc,l,mid,k,num);
        else insert(tr[now].rc,mid+1,r,k,num);
        size[now]=size[tr[now].lc]+size[tr[now].rc];
    }
    ll findkth(int &now,int l,int r,int k,int &ans)
    {
        if(now==0) now=++tot;
        if(l==r)
        {
            ans=l;
            ll temp=tr[now].c;tr[now].c=0;
            size[now]=1;
            return temp;
        }
        int mid=(l+r)/2;ll temp;
        if(mid-l+1-size[tr[now].lc]>=k)
        {
            temp=findkth(tr[now].lc,l,mid,k,ans);
        }
        else
        {
            temp=findkth(tr[now].rc,mid+1,r,k-(mid-l+1-size[tr[now].lc]),ans);
        }
        size[now]=size[tr[now].lc]+size[tr[now].rc];
        return temp;
    }
    int main()
    {
        ll n,m,q;
        scanf("%lld%lld%lld",&n,&m,&q);
        for(int i=1;i<=n;i++) tail[i]=m-1;
        tail[n+1]=n;
        for(int i=1;i<=q;i++)
        {
            scanf("%d%d",&a[i].x,&a[i].y);
            if(a[i].y==m)
            {
                int temp2;
                ll temp=findkth(root[n+1],1,n+q,a[i].x,temp2);
                if(temp2<=n) temp=temp2*m;
                printf("%lld\n",temp);
                insert(root[n+1],1,n+q,++tail[n+1],temp);
            }
            else
            {
                int temp2;
                ll temp=findkth(root[a[i].x],1,m+q,a[i].y,temp2);
                if(temp2<m) temp=m*(a[i].x-1)+temp2;
                printf("%lld\n",temp);
                insert(root[n+1],1,n+q,++tail[n+1],temp);
                temp=findkth(root[n+1],1,n+q,a[i].x,temp2);
                if(temp2<=n) temp=temp2*m;
                insert(root[a[i].x],1,m+q,++tail[a[i].x],temp);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Spring.Net框架与WCF的集成(上)
    重入与回调并发(Reentrant & CallbackConcurrency )
    WCF中的异步实现
    WCF开发时如何选择正确的实例模式(InstanceMode)?
    WCF实例与并发
    WCF消息可靠性与有序传递
    WCF实际应用之IParameterInspector扩展
    WCF中几个基本知识点整理
    HTTP与Tcp协议下双工通信的差异
    细说WCF中的会话模式
  • 原文地址:https://www.cnblogs.com/akoasm/p/9426654.html
Copyright © 2011-2022 走看看