zoukankan      html  css  js  c++  java
  • HDU 5412 CRB and Queries(区间第K大 树套树 按值建树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?

    pid=5412



    Problem Description
    There are N boys in CodeLand.
    Boy i has his coding skill Ai.
    CRB wants to know who has the suitable coding skill.
    So you should treat the following two types of queries.
    Query 1: 1 l v
    The coding skill of Boy l has changed to v.
    Query 2: 2 l r k
    This is a report query which asks the k-th smallest value of coding skill between Boy l and Boy r(both inclusive).
     

    Input
    There are multiple test cases. 
    The first line contains a single integer N.
    Next line contains N space separated integers A1A2, …, AN, where Ai denotes initial coding skill of Boy i.
    Next line contains a single integer Q representing the number of queries.
    Next Q lines contain queries which can be any of the two types.
    1 ≤ NQ ≤ 105
    1 ≤ Aiv ≤ 109
    1 ≤ l ≤ r ≤ N
    1 ≤ k ≤ r  l + 1

     

    Output
    For each query of type 2, output a single integer corresponding to the answer in a single line.
     

    Sample Input
    5 1 2 3 4 5 3 2 2 4 2 1 3 6 2 2 4 2
     

    Sample Output
    3 4
     

    Author
    KUT(DPRK)
     

    Source

    题意:

    给出一串数字。然后给出两种操作:

    1:1 L V  操作一:把下标为L的点的值替换为 V

    2:2 L R K  操作二:在[L, R]区间求第K大!

    PS:

    这题好像时间卡的比較紧!

    貌似用树状数组套主席树会T

    须要线段树套treap。


    代码例如以下:

    //#pragma warning (disable:4786)
    //#pragma comment(linker,"/STACK:102400000,102400000")  //手动扩栈
    //#include <bits/stdc++.h>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <cstdlib>
    #include <climits>
    #include <ctype.h>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <utility>
    #include <deque>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const double eps = 1e-9;
    const double PI = acos(-1.00);
    //#define PI 3.1415926535897932384626433832795
    const double e = exp(1.0);
    #define INF 0x3f3f3f3f
    //#define INF 1e18
    //typedef long long LL;
    //typedef __int64 LL;
    #define ONLINE_JUDGE
    #ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    #endif
    
    
    #define N 600010
    #define M 100010
    struct treap
    {
        int key,wht,count,sz,ch[2];
    } tp[N*15];
    int tree[N<<1];
    int nodecount,root;
    int IDX(int l,int r)
    {
        return l+r | l!=r;
    }
    void init()
    {
        tp[0].sz=0;
        tp[0].wht=-INF;
        nodecount=0;
        root=0;
    }
    void update(int x)
    {
        tp[x].sz=tp[tp[x].ch[0]].sz+tp[x].count+tp[tp[x].ch[1]].sz;
    }
    void rotate(int &x,int t)
    {
        int y=tp[x].ch[t];
        tp[x].ch[t]=tp[y].ch[!t];
        tp[y].ch[!t]=x;
        update(x);
        update(y);
        x=y;
    }
    void insert(int &x,int t)
    {
        if(! x)
        {
            x=++nodecount;
            tp[x].key=t;
            tp[x].wht=rand();
            tp[x].count=1;
            tp[x].ch[0]=tp[x].ch[1]=0;
        }
        else if(tp[x].key==t)  tp[x].count++;
        else
        {
            int k=tp[x].key<t;
            insert(tp[x].ch[k],t);
            if(tp[x].wht<tp[tp[x].ch[k]].wht) rotate(x,k);
        }
        update(x);
    }
    void erase(int &x,int t)
    {
        if(tp[x].key==t)
        {
            if(tp[x].count==1)
            {
                if(! tp[x].ch[0] && ! tp[x].ch[1])
                {
                    x=0;
                    return;
                }
                rotate(x,tp[tp[x].ch[0]].wht<tp[tp[x].ch[1]].wht);
                erase(x,t);
            }
            else tp[x].count--;
        }
        else erase(tp[x].ch[tp[x].key<t],t);
        update(x);
    }
    int select(int x,int t)
    {
        if(! x) return 0;
        if(tp[x].key>t) return select(tp[x].ch[0],t);
        return tp[x].count+tp[tp[x].ch[0]].sz+select(tp[x].ch[1],t);
    }
    int a[N],b[N],ord[M][5],lb;
    int n,m,tt;
    int search(int x)
    {
        int l=1,r=b[0],mid;
        while (l<=r)
        {
            mid=(l+r)>>1;
            if(b[mid]==x) return mid;
            if(b[mid]<x) l=mid+1;
            else r=mid-1;
        }
    }
    void treeinsert(int l,int r,int i,int x)
    {
        insert(tree[IDX(l,r)],x);
        if(l==r) return;
        int m=(l+r)>>1;
        if(i<=m) treeinsert(l,m,i,x);
        else treeinsert(m+1,r,i,x);
    }
    void treedel(int l,int r,int i,int x)
    {
        erase(tree[IDX(l,r)],x);
        if(l==r) return;
        int m=(l+r)>>1;
        if(i<=m) treedel(l,m,i,x);
        else treedel(m+1,r,i,x);
    }
    int query(int l,int r,int x,int y,int k)
    {
        if(l==r) return l;
        int m=(l+r)>>1;
        int ans=select(tree[IDX(l,m)],y)-select(tree[IDX(l,m)],x);
        if(ans>=k) return query(l,m,x,y,k);
        return query(m+1,r,x,y,k-ans);
    }
    int main ()
    {
        while (~scanf("%d",&n))
        {
            b[0]=1;
            lb=0;
            memset(tree,0,sizeof(tree));
            init();
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&a[i]);
                b[++lb]=a[i];
            }
            scanf("%d",&m);
            for(int i=1; i<=m; i++)
            {
                int op;
                int x,y,c;
                scanf("%d",&op);
                if(op == 2)
                {
                    scanf("%d %d %d",&x,&y,&c);
                    ord[i][1]=1;
                    ord[i][2]=x;
                    ord[i][3]=y;
                    ord[i][4]=c;
                }
                else
                {
                    scanf("%d %d",&x,&y);
                    ord[i][1]=2;
                    ord[i][2]=x;
                    ord[i][3]=y;
                    b[++lb]=y;
                }
            }
            sort(b+1,b+1+lb);
            for(int i=1; i<=lb; i++)
                if(b[i]!=b[b[0]]) b[++b[0]]=b[i];
            for(int i=1; i<=n; i++)
            {
                a[i]=search(a[i]);
                treeinsert(1,b[0],a[i],i);
            }
            for(int i=1; i<=m; i++)
            {
                if(ord[i][1]==1)
                    printf("%d
    ",b[query(1,b[0],ord[i][2]-1,ord[i][3],ord[i][4])]);
                else
                {
                    treedel(1,b[0],a[ord[i][2]],ord[i][2]);
                    a[ord[i][2]]=search(ord[i][3]);
                    treeinsert(1,b[0],a[ord[i][2]],ord[i][2]);
                }
            }
        }
        return 0;
    }


  • 相关阅读:
    service structure flowchart with full stack functionality in a brife map
    service structure flowchart [mobile to server via HTTP RESTful API and TCP/IP in a map]
    service structure flowchart [mobile to server via TCP/IP protocol]
    service structure flowchart [mobile to server via HTTP RESTful API]
    Python -- machine learning, neural network -- PyBrain 机器学习 神经网络
    Deploying OpenFire for IM (instant message) service (TCP/IP service) with database MySQL , client Spark on linux部署OpenFire IM 消息中间件服务
    做自己想做的事,成为想成为的人(转)
    PCB工艺要求
    看了三遍,沉默了五天
    850和940红外发射管的区别
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6893856.html
Copyright © 2011-2022 走看看