1. 程式人生 > >[永不止步-2017]_區間第K大-線段樹維護

[永不止步-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;
    }