• SPOJ:K-Query Online(归并树)


    Given a sequence of n numbers a1, a2, ..., an and a number of k-queries. A k-query is a triple (i, j, k) (1 ≤ i ≤ j ≤ n). For each k-query (i, j, k), you have to return the number of elements greater than k in the subsequence ai, ai+1, ..., aj.

    Input

    • Line 1: n (1 ≤ n ≤ 30000).
    • Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 109).
    • Line 3: q (1 ≤ q ≤ 200000), the number of k- queries.
    • In the next q lines, each line contains 3 numbers a, b, c representing a k-query. You should do the following:
      • i = a xor last_ans
      • j = b xor last_ans
      • k = c xor last_ans
      After that 1 ≤ i ≤ j ≤ n, 1 ≤ k ≤ 109 holds.
      Where last_ans = the answer to the last query (for the first query it's 0).

    Output

    For each k-query (i, j, k), print the number of elements greater than k in the subsequence ai, ai+1, ..., aj in a single line.

    Example

    Input:
    6
    8 9 3 5 1 9
    5
    2 3 5
    3 3 7
    0 0 11
    0 0 2
    3 7 4
    
    Output:
    1
    1
    0
    0
    2

    [Edited by EB]

    There are invalid queries. Assume the following:

    • if i < 1: i = 1
    • if j > n: j = n
    • if i > j: ans = 0

    题意:在线询问区间大于K的个数。

    思路:线段树,每个节点加vector排序。

    (第一次写归并树,AC on one go!

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1200010;
    vector<int>v[maxn];
    int a[maxn];
    void build(int Now,int L,int R)
    {
        if(L==R) { v[Now].push_back(a[L]); return ;}
        int Mid=(L+R)>>1;
        build(Now<<1,L,Mid);
        build(Now<<1|1,Mid+1,R);
        int i=0,j=0,L1=v[Now<<1].size()-1,L2=v[Now<<1|1].size()-1;
        while(i<=L1||j<=L2){
            while(i<=L1&&j<=L2){
                if(v[Now<<1][i]<=v[Now<<1|1][j]) v[Now].push_back(v[Now<<1][i++]);
                else v[Now].push_back(v[Now<<1|1][j++]);
            }
            while(j>L2&&i<=L1) v[Now].push_back(v[Now<<1][i++]);
            while(i>L1&&j<=L2) v[Now].push_back(v[Now<<1|1][j++]);
        }
    }
    int query(int Now,int L,int R,int l,int r,int k)
    {
        if(l<=L&&r>=R) {
            int pos=lower_bound(v[Now].begin(),v[Now].end(),k)-v[Now].begin();
            return v[Now].size()-pos;
        }
        int Mid=(L+R)>>1,res=0;
        if(l<=Mid) res+=query(Now<<1,L,Mid,l,r,k);
        if(r>Mid) res+=query(Now<<1|1,Mid+1,R,l,r,k);
        return res;
    }
    int main()
    {
        int N,Q,ans=0,i,j,k;
        scanf("%d",&N);
        for(i=1;i<=N;i++) scanf("%d",&a[i]);
        build(1,1,N);
        scanf("%d",&Q);
        while(Q--){
            scanf("%d%d%d",&i,&j,&k);
            i=i^ans; j=j^ans; k=k^ans;
            if(i<1) i=1; if(j>N) j=N;
            if(i>j) ans=0;
            else ans=query(1,1,N,i,j,k+1);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    IntelliJ Idea 常用快捷键 列表(实战终极总结!!!!)
    spring+spring mvc+mybatis 实现主从数据库配置
    Elasticsearch java api 基本搜索部分详解
    Elasticsearch java api 常用查询方法QueryBuilder构造举例
    Elasticsearch JavaApi
    [搜索]ElasticSearch Java Api(一) -添加数据创建索引
    Java Elasticsearch新手入门教程
    转载 Elasticsearch开发环境搭建(EclipseMyEclipse + Maven)
    SpringQuartz 实现定时任务调度
    Mysql语句查询优化
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9053854.html
Copyright © 2020-2023  润新知