• lightoj1087 【线段树】


    题意:
    给你n个数,然后给你q个询问,有两种询问:
    a: 表示在右边插入一个数
    c:表示从左边拿出一个数,然后输出;
    思路:
    一开始在想,自己手上的黑科技:线段树和树状数组
    线段树上的操作:
    求区间最大,没说区间第几个啊;
    树状数组:
    搞一发前缀和,妈个鸡,树状数组还需要知道下标和位置;
    还有什么:
    数组,感觉黑科技没什么了;
    然后。。。
    线段树维护区间有多少个数,好像很对啊,初始化建树就是n+q长度的区间,然后每次插入就是第n+i个,每次插入,删除都是log级别的;

    后来线段树打完居然没什么错,感动啊;

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=2e5+10;
    
    struct SegT{
        bool flag;
        int left,right;
        int num,v;
    };
    SegT q[N*4];
    int n,Q;
    
    void Build(int num,int L,int R)
    {
        q[num].left=L;
        q[num].right=R;
        if(L==R)
        {
            if(L<=n)
            {
                scanf("%d",&q[num].v);
                q[num].flag=true;
                q[num].num=1;
                return;
            }
            else
            {
                q[num].flag=false;
                q[num].num=0;
                return;
            }
        }
        int mid=(L+R)/2;
        Build(2*num, L,mid);
        Build(2*num+1,mid+1,R);
        q[num].num=q[2*num].num+q[2*num+1].num;
    }
    
    void add(int num,int id,int x)
    {
        if(q[num].left==id&&q[num].left==q[num].right)
        {
            q[num].flag=true;
            q[num].v=x;
            q[num].num=1;
            return;
        }
        int mid=(q[num].left+q[num].right)/2;
        if(mid>=id)
            add(2*num,id,x);
        else
            add(2*num+1,id,x);
        q[num].num=q[2*num].num+q[num*2+1].num;
    }
    
    int DEL(int num,int id)
    {
        if(q[num].left==q[num].right)
        {
            q[num].num=0;
            q[num].flag=false;
            return q[num].v;
        }
        int ans=0;
        if(q[2*num].num>=id)
            ans=DEL(2*num,id);
        else
            ans=DEL(2*num+1,id-q[2*num].num);
        q[num].num=q[2*num].num+q[2*num+1].num;
        return ans;
    }
    
    int main()
    {
        int T,cas=1;
        scanf("%d",&T);
        while(T--)
        {
            char txp[5];
            int temp;
            scanf("%d%d",&n,&Q);
            Build(1,1,n+Q);
            printf("Case %d:
    ",cas++);
            for(int i=1;i<=Q;i++)
            {
                scanf("%s%d",txp,&temp);
                if(txp[0]=='a')
                    add(1,n+i,temp);
                else
                {
                    if(q[1].num<temp)
                        puts("none");
                    else
                        printf("%d
    ",DEL(1,temp));
                }
            }
        }
        return 0;
    }
    


  • 相关阅读:
    mogodb 设置用户名密码认证
    axon mogoconfig
    ListUtils 对 list数据 分组 ,统计,求和 。。。
    jQuery 之 dom操作
    学习Java第二天
    字节跳动spring面试题,你能回答出几个
    CH340芯片选型
    Django的路由转换器的使用
    Vue之cli脚手架
    String中split(regex,limit)方法讲解
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777537.html
Copyright © 2020-2023  润新知