codeup24698 统计

 

题目描述

统计statistic

【问题描述】

给定N个数,有M个询问。每次询问一段区间内有没有出现过Xi这个数。

【输入格式】

第一行一个整数N。

第二行N个正整数表示给定的N个数。

第三行一个整数M。

以下M行每行三个整数li,ri和Xi;表示询问区间是[li, ri],询问数字是Xi。

【输出格式】

对于每一次询问,输出一个字符。0表示没出现,1表示出现了。

【样例输入输出】

statistic.in

statistic.out

5

1234567 666666 3141593 666666 4343434

5

1 5 3141593

1 5 578202

2 4 666666

4 4 7135610

1 1 1234567

10101

【数据说明】

40%的数据满足:N≤1000,M≤1000

100%的数据满足:N≤105,M≤105,Xi≤109

可以选择如下套餐:

套餐一:线段树+归并排序+二分查找

套餐二:主席树

套餐三:可持久化01trie

套餐四:分块

套餐五:莫队

(总之就是什么都可以水。。。)

(归并排序是个好东西。。。build的时候可以直接降一个log。。。不过查询的时候依旧是log2。。。)

(当然太蒻辣只会写线段树。。。)

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <cmath>

using namespace std;

const int N = 1e5 + 10;

vector<int> node[N * 4];

int n, m;

void build(int id, int l, int r) {
    int m = (l + r) >> 1;
    if(l == r) {
        int val;
        scanf("%d", &val);
        node[id].push_back(val);
        return;
    }
    build(id << 1, l, m);
    build(id << 1 | 1, m + 1, r);
    vector<int> &v1 = node[id << 1];
    vector<int> &v2 = node[id << 1 | 1];
    vector<int> &v = node[id];
    for(int p1 = 0, p2 = 0, i = 1 ; i <= v1.size() + v2.size() ; i ++) {
        if(p1 == v1.size()) {
            v.push_back(v2[p2 ++]);
        } else if(p2 == v2.size()) {
            v.push_back(v1[p1 ++]);
        } else {
            if(v1[p1] < v2[p2]) {
                v.push_back(v1[p1 ++]);
            } else {
                v.push_back(v2[p2 ++]);
            }
        }
    }
}

int ask(int id, int x, int l, int r, int L, int R) {
    int M = (L + R) >> 1;
    if(L > r || R < l) return 0;
    if(l <= L && R <= r) return *lower_bound(node[id].begin(), node[id].end(), x) == x;
    return ask(id << 1, x, l, r, L, M) || ask(id << 1 | 1, x, l, r, M + 1, R);
}

int main() {
    scanf("%d", &n);
    build(1, 1, n);
    scanf("%d", &m);
    for(int i = 1, l, r, x ; i <= m ; i ++) {
        scanf("%d%d%d", &l, &r, &x);
        printf("%d", ask(1, x, l, r, 1, n));
    }
}

  

转载于:https://www.cnblogs.com/KingSann/articles/7480002.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值