P3567 [POI2014]KUR-Couriers 主席树

这个题比一般主席树还要简单,但是用来练习主席树再好不过了,在这里我再放一下主席树板子。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;i++)
#define lv(i,a,n) for(register int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1 << 30;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < ‘0‘ || c > ‘9‘)
        if(c == ‘-‘) op = 1;
    x = c - ‘0‘;
    while(c = getchar(), c >= ‘0‘ && c <= ‘9‘)
        x = x * 10 + c - ‘0‘;
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar(‘-‘), x = -x;
    if(x >= 10) write(x / 10);
    putchar(‘0‘ + x % 10);
}
const int N = 2e5 + 5;
struct node
{
    int l,r,sum;
}tree[N * 20];
int root[N];
int cnt = 0,n,m;
void insert(int lst,int &now,int l,int r,int pos)
{
    tree[++cnt] = tree[lst];
    now = cnt;
    ++tree[now].sum;
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(pos <= mid) insert(tree[lst].l,tree[now].l,l,mid,pos);
    else insert(tree[lst].r,tree[now].r,mid + 1,r,pos);
}
int query(int lst,int now,int l,int r,int val)
{
    if(l == r) return tree[now].sum > val ? l : 0;;
    int tmp = tree[tree[now].l].sum - tree[tree[lst].l].sum;
//    cout<<lst<<" "<<now<<" "<<l<<" "<<r<<endl;
    int mid = (l + r) >> 1;
    if(tmp > val) return query(tree[lst].l,tree[now].l,l,mid,val);
    else if(tree[tree[now].r].sum - tree[tree[lst].r].sum > val)
    return query(tree[lst].r,tree[now].r,mid + 1,r,val);
    return 0;
}
int a,tot;
int main()
{
    read(n);read(m);
    duke(i,1,n)
    {
        read(a);
        insert(root[i - 1],root[i],1,n,a);
    }
    /*for(int i = 1;i <= 20;i++)
    {
        printf("%d %d %d\n",tree[i].l,tree[i].r,tree[i].sum);
    }*/
    while(m--)
    {
        int x,y;
        read(x);read(y);
        printf("%d\n",query(root[x - 1],root[y],1,n,(y - x + 1) >> 1));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/DukeLv/p/10160990.html

时间: 2024-10-08 23:35:53

P3567 [POI2014]KUR-Couriers 主席树的相关文章

BZOJ 3524: [Poi2014]Couriers( 主席树 )

卡我空间.... 这道题应该是主席树入门题...无修改 , 离散化都不用...出题人业界良心啊 一开始的空白树我 build 出来结果就多了整整 2n 个 Node , 然后就 MLE 了... ( 双倍经验 , 另一道见上图 ) ---------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring&g

[BZOJ2223][BZOJ3524][Poi2014]Couriers 主席树

3524: [Poi2014]Couriers Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 2436  Solved: 960[Submit][Status][Discuss] Description 给一个长度为n的序列a.1≤a[i]≤n.m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0. Input 第一行两个数n,m.第二行n个数,a[i].接下来m行,

BZOJ 3524 POI 2014 Couriers 主席树

题目大意 给出一个序列,问一段区间内有没有出现过一半以上的数字. 思路 用主席树取区间出来,在权值线段树上找. CODE #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 500010 #define MAXR 10000010 using namespace std

3524: [Poi2014]Couriers -- 主席树

3524: [Poi2014]Couriers Time Limit: 20 Sec  Memory Limit: 256 MB Description 给一个长度为n的序列a.1≤a[i]≤n.m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0. Input 第一行两个数n,m.第二行n个数,a[i].接下来m行,每行两个数l,r,表示询问[l,r]这个区间. Output m行,每行对应一个答案. Sample

[bzoj3524][Poi2014]Couriers_主席树

Couriers bzoj-3524 Poi-2014 题目大意:给定n个数的序列,询问区间内是否存在一个在区间内至少出现了(区间长度>>1)次的数.如果有,输出该数,反之输出0. 注释:$1\le n,m\le 5\cdot 10^5$. 想法:主席树裸题. 主流做法就是弄一个Existence数组询问有没有这样的数,然后查询区间中位数即可. 但是可以在query的时候强行查询,因为没有输出0,直接输出即可. 最后,附上丑陋的代码... ... #include <iostream&g

BZOJ_3524_[Poi2014]Couriers_主席树

题意:给一个长度为n的序列a.1≤a[i]≤n. m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0. 分析: 区间众数我们可以用主席树搞定 具体地,比较左右子树siz大小即可 代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 500050 int t

bzoj 3524 [POI2014]KUR-Couriers (主席树)

题目大意:给你一个序列,求某个区间出现次数大于一半的数是什么 主席树裸题,刷刷水题提升自信= = 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define ll long long 5 #define il inline 6 #define N 500100 7 using namespace std; 8 //re 9 int n,m,tot; 10 int a[N],root[

luogu P3567 [POI2014]KUR-Couriers

二次联通门 : luogu P3567 [POI2014]KUR-Couriers MMP 指针 RE + MLE + WA..... 不得已...向黑恶的数组实力低头 /* 指针 */ #include <algorithm> #include <cstdio> #define Max 2000009 void read (int &now) { now = 0; register char word = getchar (); while (word < '0'

【复习笔记】主席树

昨天在写带修改主席树的时候,咸鱼zcysky发现自己似乎根本不会写主席树 于是正好找个空复习下-- 主席树的原理不用我扯了,主席树为啥能求k大,大概在它可以用历史版本存下区间的前缀和,求的时候差分下就能提出我要求的区间. 不过这么搞的话不要忘了离散化. 1.kth number 就是上面的裸题,不要手贱写bits就好. 1 #include<iostream> 2 #include<cstdio> 3 #define N 100010 4 #include<algorithm