zoukankan      html  css  js  c++  java
  • 列队

    传送门

    解法:

    a11 a12 a13
    a21 a22 a23
    a31 a32 a33

    我们发现移走一个点只会影响
    该点所在行
    以及最后一列
    所以很容易能想到维护每一行以及最后一列
    每次删两个点,加两个点
    并用动态开点线段树维护

    删点方法:

    对线段树中每个节点处理子节点个数
    记作sz[k]
    递归找到要删的节点(设在线段树中位置为k)
    使k位置及k位置所有父节点的sz[]-1
    搜取值时就用sz[]作为判断递归条件
    这样 要被删掉的点永远不可能被访问
    相当于被删除了

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<map>
    #define inf 2000000000
    #define min(x,y) ((x)<(y)?(x):(y))
    #define max(x,y) ((x)>(y)?(x):(y))
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    int n,m,now,q,p;
    int tot=0,o[300010],root[300010],sz[10000010],tl[10000010],tr[10000010];
    ll t,val[10000010];
    inline int build()
    {
        tot++;
        tl[tot]=tr[tot]=val[tot]=0;
        return tot;
    }
    inline int get_sz(int l,int r)
    {
        if(now==n+1)
        {
            if(r<=n) return r-l+1;
            if(l<=n) return n-l+1;
            return 0;
        }
        if(r<m) return r-l+1;
        if(l<m) return m-l;
        return 0;
    }
    ll ask_val(int &k,int l,int r,int x)
    {
        if(!k)
        {
            k=build();
            sz[k]=get_sz(l,r);
            if(l==r)
            {
                if(now==n+1) val[k]=1ll*l*m;
                else val[k]=1ll*(now-1)*m+l;
            }
        }
        sz[k]--;
        if(l==r) return val[k];
        int mid=(l+r)>>1;
        if(x<=sz[tl[k]]||(!tl[k]&&x<=(mid-l+1))) return ask_val(tl[k],l,mid,x);
        else{
            if(!tl[k]) x=x-(mid-l+1);
            else x=x-sz[tl[k]];
            return ask_val(tr[k],mid+1,r,x);
        }
    }
    void update(int &k,int l,int r,int x,ll v)
    {
        if(!k)
        {
            k=build();
            sz[k]=get_sz(l,r);
            if(l==r) val[k]=v;
        }
        sz[k]++;
        if(l==r) return;
        int mid=(l+r)>>1;
        if(x<=mid) update(tl[k],l,mid,x,v);
        else update(tr[k],mid+1,r,x,v);
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&q);
        p=max(n,m)+q;
        rep(i,1,q)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            if(y==m)
            {
                now=n+1;
                t=ask_val(root[n+1],1,p,x);
            }
            else
            {
                now=x;
                t=ask_val(root[x],1,p,y);
            }
            printf("%lld
    ",t);
            if(y==m)
            {
                o[n+1]++;
                update(root[n+1],1,p,n+o[n+1],t);
            }
            else
            {
                now=n+1;
                o[n+1]++;
                update(root[n+1],1,p,n+o[n+1],t);
                t=ask_val(root[n+1],1,p,x);
                now=x;
                o[x]++;
                update(root[x],1,p,m-1+o[x],t);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    TOPCoder(一)Time
    highchart柱状图 series中data的数据构造
    (转)myeclipse工程 junit不能运行 ClassNotFoundException
    reserve和resize区别
    ++ fatal error C1083: 无法打开预编译头文件:“.Debug outer.pch”
    初学lua --lua嵌入c++的一个问题(初始化lua出错,版本问题)
    .NET中字符串split的C++实现
    成员函数指针与高效C++委托 (delegate)
    Android.mk 用法介绍
    cocos2d-x学习之旅(五):1.5 使用eclipse编译cocos2d-x示例项目,创建cocos2d-x android项目并部署到真机
  • 原文地址:https://www.cnblogs.com/MYsBlogs/p/10990805.html
Copyright © 2011-2022 走看看