J - [永不止步-2017]_区间第K大-线段树维护

  • J - [永不止步-2017]_区间第K大
  • 把线段树的结点的数据域设置为vector类型即可别的操作为区间更新模板
  • 思路就是这样runtime error暂时没改对
  • #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    #define maxn 5000000
    #define lson root<<1
    #define rson root<<1|1
    int t,n,q,op,l,r,c;
    bool cmp(int a,int b)
    {
        return a>b;
    }
    struct node
    {
        vector<int>num;
        int lazy,l,r;
        int mid()
        {
            return (l+r)/2;
        }
    } tree[maxn];
    void pushup(int root)
    {
        vector<int>temp;
        temp=tree[lson].num;
        int len=tree[rson].num.size();
        for(int i=0; i<len; i++)
            temp.push_back(tree[rson].num[i]);
        sort(temp.begin(),temp.end(),cmp);
        len=temp.size();
        tree[root].num.clear();
        for(int i=0; i<len&&i<5; i++)
            tree[root].num.push_back(temp[i]);
    }
    void push_down(int root)
    {
        if(tree[root].lazy!=0)
        {
            tree[lson].lazy+=tree[root].lazy;
            tree[rson].lazy+=tree[root].lazy;
            int len=tree[lson].num.size();
            for(int i=0; i<len; i++)
                tree[lson].num[i]+=tree[root].lazy;
            len=tree[rson].num.size();
            for(int i=0; i<len; i++)
                tree[rson].num[i]+=tree[root].lazy;
            tree[root].lazy=0;
        }
    }
    void build(int l,int r,int root)
    {
        tree[root].num.clear();
        tree[root].l=l;
        tree[root].r=r;
        tree[root].lazy=0;
        if(l==r)
        {
            cin>>t;
            tree[root].num.push_back(t);
            return;
        }
        build(l,tree[root].mid(),lson);
        build(tree[root].mid()+1,r,rson);
    }
    void updata(int l,int r,int root,int add)
    {
        if(l<=tree[root].l&&tree[root].r<=r)
        {
            int len=tree[root].num.size();
            for(int i=0; i<len; i++)
                tree[root].num[i]+=add;
            tree[root].lazy+=add;
            return ;
        }
        push_down(root);
        if(r<=tree[root].mid())
            updata(l,r,lson,add);
        else if(l>tree[root].mid())
            updata(l,r,rson,add);
        else
        {
            updata(l,tree[root].mid(),lson,add);
            updata(tree[root].mid()+1,r,rson,add);
        }
        pushup(root);
    }
    vector<int>query(int l,int r,int root)
    {
        if(l<=tree[root].l&&tree[root].r<=r)
            return tree[root].num;
        push_down(root);
        vector<int>tl,tr;
        if(r<=tree[root].mid())
            tl=query(l,r,lson);
        else if(l>tree[root].mid())
            tr=query(l,r,rson);
        else
        {
            tl=query(l,tree[root].mid(),lson);
            tr=query(tree[root].mid()+1,r,rson);
        }
        int len=tl.size();
        for(int i=0; i<len; i++)
            tr.push_back(tl[i]);
        sort(tr.begin(),tr.end(),cmp);
        tl.clear();
        len=tr.size();
        for(int i=0; i<len&&i<5; i++)
            tl.push_back(tr[i]);
        return tl;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        vector<int>out;
        while(cin>>n>>q)
        {
            build(1,n,1);
            while(q--)
            {
                cin>>op>>l>>r>>c;
                if(op==1)
                    updata(l,r,1,c);
                else
                {
                    out=query(l,r,1);
                    cout<<out[c-1]<<endl;
                }
            }
        }
        return 0;
    }
    
  •  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值