zoukankan      html  css  js  c++  java
  • [2016北京集训测试赛5]小Q与内存-[线段树的神秘操作]

    Description

    Solution

    哇真的异常服气。。线段树都可以搞合并和拆分的啊orzorz。神的世界我不懂

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int M=20000010;
    const int N=200010;
    int sz[M],lc[M],rc[M],tag[M],rt[N],all_work,cnt;
    int _new(int x=1)
    {
        int o=++cnt;
        tag[o]=x-1;
        sz[o]=1<<tag[o];
        lc[o]=rc[o]=0;
        return cnt;
    }
    void pushdown(int o)
    {
        if (!tag[o]) return;
        lc[o]=_new(tag[o]);
        rc[o]=_new(tag[o]);
        tag[o]=0;
    }
    int split(int o,int k)
    {
        int now=++cnt,re=now;
        pushdown(o);
        while (lc[o]||rc[o])
        {
            tag[now]=0;sz[now]=k;sz[o]-=k;
            if (k<=sz[lc[o]])
            {
                lc[now]=_new();rc[now]=0;
                now=lc[now];o=lc[o];
            } else
            {
                rc[now]=_new();lc[now]=lc[o];
                k-=sz[lc[o]];lc[o]=0;
                now=rc[now];o=rc[o];
            }
            pushdown(o);
        }
        tag[now]=tag[o]=0;
        sz[now]=k;sz[o]-=k;
        return re;
    }
    int merge(int x,int y)
    {
        if (!x||!y) return x+y;
        lc[x]=merge(lc[x],lc[y]);
        rc[x]=merge(rc[x],rc[y]);
        sz[x]+=sz[y];
        return x;
    }
    int query(int x,int k)
    {
        int o=rt[x];
        if (x>all_work||k>=sz[o]) return -1;
        int re=0;
        while (lc[o]||rc[o])
        {
            re<<=1;
            if (lc[o]&&k<sz[lc[o]]) o=lc[o];
            else k-=sz[lc[o]],re|=1,o=rc[o];
        }
        return re*(1<<tag[o])+k;
    }
    int T,n,root;
    int _type,_k,_i,_p;
    void clear()
    {
        cnt=all_work=0;
        root=_new(31);
    }
    int main()
    {
        scanf("%d",&T);
        while (T--)
        {
            clear();
            scanf("%d",&n);
            for (int i=1;i<=n;i++)
            {
                scanf("%d",&_type);
                if (_type==1)
                {
                    scanf("%d",&_k);
                    all_work++;
                    rt[all_work]=0;
                    if (sz[root]<_k) {printf("failed
    ");continue;}
                    rt[all_work]=split(root,_k);
                    printf("ok
    ");
                }
                if (_type==2)
                {
                    scanf("%d",&_i);
                    if (_i>all_work||!rt[_i]) {printf("failed
    ");continue;}
                    root=merge(root,rt[_i]);rt[_i]=0;
                    printf("ok
    ");
                }
                if (_type==3)
                {
                    scanf("%d%d",&_i,&_p);
                    int ans=query(_i,_p);
                    if (ans!=-1) printf("%d
    ",ans);
                    else printf("failed
    ");
                }
            }
        }
    }
  • 相关阅读:
    堆和栈的区别!
    产品经理和程序员的爱恨情仇
    字符串MD5加密运算
    事件驱动模型。。。。有时间弄
    Apache服务器httpd.exe进程占用cpu超过50%的解决方法
    ZigBee Xbee S2通讯设置
    pipe-filter 真难找啊
    javacomm64位用不了,可以使用RXTXcomm for x64
    导入 sun.net.TelnetInputStream; 报错
    linux下gedit读取txt乱码解决办法
  • 原文地址:https://www.cnblogs.com/coco-night/p/9640928.html
Copyright © 2011-2022 走看看