zoukankan      html  css  js  c++  java
  • 刷题总结——序列操作(权值线段树套树状数组)

    题目:

    题目描述

    给出序列 a1,a2,…,an(0≤ai≤109),有关序列的两种操作。

    1. ai(1≤i≤n)变成 x(0≤x≤109)。

    2. 求 al,al+1,…,ar(1≤l≤r≤n)第 k(1≤k≤r-l+1)小。

    输入格式

    第一行包含两个数 n(1≤n≤2×104)和 m(1≤m≤2×104),表示序列长度和操作次数。

    接下来一行 n 个数,以空格隔开,表示 a1,a2,…,an 。

    接下来m行,每行为以下两种格式之一:

    • 0 i x ,  表示 ai=x。
    • 1 l r k ,求 al,al+1,…,ar 的第 k 小。

    输出格式

    对于每次询问,输出单独的一行表示答案。

    样例数据 1

    输入  [复制]

     
    5 3 
    1 2 3 4 5 
    1 1 5 3 
    0 3 5 
    1 1 5 3

    输出


    4

    题解:

      待修改的权值线段树的模板题

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    
    int getint()
    {
        int i=0,f=1;char c;
        for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
        if(c=='-')f=-1,c=getchar();
        for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
        return i*f;
    }
    
    const int N=2e4+5,M=2e6+5;
    struct node
    {
        int op,x,y,k;
    }q[N];
    struct tree
    {
        int lc,rc,size;
    }tr[M];
    int n,m,len,tot,a[N],b[N<<1],bit[N],pos[N];
    
    void dic_init()
    {
        sort(b+1,b+len+1);
        len=unique(b+1,b+len+1)-b-1;
        for(int i=1;i<=n;i++)
            a[i]=lower_bound(b+1,b+len+1,a[i])-b;
        for(int i=1;i<=m;i++)
            if(!q[i].op)
                q[i].y=lower_bound(b+1,b+len+1,q[i].y)-b;
    }
    
    void Insert(int &k,int l,int r,int x)
    {
        if(!k)k=++tot;
        tr[k].size++;
        if(l==r)return;
        int mid=l+r>>1;
        if(x<=mid)Insert(tr[k].lc,l,mid,x);
        else Insert(tr[k].rc,mid+1,r,x);
    }
    
    void Add(int x)
    {
        for(int i=x;i<=n;i+=i&(-i))
            Insert(bit[i],1,len,a[x]);
    }
    
    void Delete(int k,int l,int r,int x)
    {
        tr[k].size--;
        if(l==r)return;
        int mid=l+r>>1;
        if(x<=mid)Delete(tr[k].lc,l,mid,x);
        else Delete(tr[k].rc,mid+1,r,x);
    }
    
    void Rec(int x)
    {
        for(int i=x;i<=n;i+=i&(-i))
            Delete(bit[i],1,len,a[x]);
    }
    
    void pre(int x,int y)
    {
        for(int i=x;i>0;i-=i&(-i))
            pos[i]=bit[i];
        for(int i=y;i>0;i-=i&(-i))
            pos[i]=bit[i];
    }
    
    int calc(int x,int y)
    {
        int res=0;
        for(int i=x;i>0;i-=i&(-i))
            res+=tr[tr[pos[i]].lc].size;
        for(int i=y;i>0;i-=i&(-i))
            res-=tr[tr[pos[i]].lc].size;
        return res;
    }
    
    void trans(int x,int y,int f)
    {
        for(int i=x;i>0;i-=i&(-i))
            if(!f)pos[i]=tr[pos[i]].lc;
            else pos[i]=tr[pos[i]].rc;
        for(int i=y;i>0;i-=i&(-i))
            if(!f)pos[i]=tr[pos[i]].lc;
            else pos[i]=tr[pos[i]].rc;
    }
    
    int query(int rt1,int rt2,int l,int r,int k)
    {
        if(l==r)return l;
        int delta=calc(rt1,rt2);
        int mid=l+r>>1;
        if(delta>=k)
        {
            trans(rt1,rt2,0);
            return query(rt1,rt2,l,mid,k);
        }
        else 
        {
            trans(rt1,rt2,1);
            return query(rt1,rt2,mid+1,r,k-delta);
        }
    }
    
    int main()
    {
        //freopen("a.in","r",stdin);
        n=getint(),m=getint();
        for(int i=1;i<=n;i++)
            a[i]=getint(),b[++len]=a[i];
        for(int i=1;i<=m;i++)
        {
            q[i].op=getint();
            q[i].x=getint();
            q[i].y=getint();
            if(!q[i].op)b[++len]=q[i].y;
            else q[i].k=getint();
        }    
        
        dic_init();
        for(int i=1;i<=n;i++)Add(i);
        
        for(int i=1;i<=m;i++)
            if(!q[i].op)
            {
                Rec(q[i].x);
                a[q[i].x]=q[i].y;
                Add(q[i].x);
            }
            else
            {
                pre(q[i].y,q[i].x-1);
                cout<<b[query(q[i].y,q[i].x-1,1,len,q[i].k)]<<'
    ';
            }
        return 0;
    }
  • 相关阅读:
    vector向量容器的一些基本操作
    OpenCV鼠标画图例程,鼠标绘制矩形
    网络安全学习笔记--《暗战强人:黑客攻防入门全程图解》
    遗传算法解决TSP问题实现以及与最小生成树的对比
    基于opencv的手写数字字符识别
    最小生成树
    opencv基本图像操作
    使用vs2010 opencv2.4.4编译release版本程序
    【machine translate】deep learning seq2seq
    【DL】物体识别与定位
  • 原文地址:https://www.cnblogs.com/AseanA/p/7201294.html
Copyright © 2011-2022 走看看