我们可以先离散化,然后建立权值的可持久化线段树,记录每个数出现的次数,对于区间询问直接判断左右儿子的cnt是不是大于(r-k+1)/2,然后递归到最后一层要是还是大于就有,否则不存在。

  反思:挺简单一道题调了一个晚上加一个几节课= =,原因是这道题的空间给的是128MB,那么就会有比较严重的卡空间的地方,开始我的线段树是记录的左右儿子和代表的区间,这样会MLE,那么我们可以不记录代表的区间然后递归的时候传上去区间也可以起到同样的效果。

/**************************************************************
    Problem: 3524
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:7392 ms
    Memory:125808 kb
****************************************************************/
 
//By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 500010
 
using namespace std;
 
struct segment {
    int cnt;
    int son[];
    segment() {
        cnt=;
        memset(son,,sizeof son);
    }
}t[];
 
struct rec {
    int num,key;
}a[maxn];
 
int n,m,tot;
int rot[maxn],ans[maxn];
 
bool cmp1(rec x,rec y) {
    return x.key<y.key;
}
 
bool cmp2(rec x,rec y) {
    return x.num<y.num;
}
 
void build(int &x,int l,int r) {
    if (!x) x=++tot;
    if (l==r) return ;
    int mid=l+r>>;
    build(t[x].son[],l,mid); build(t[x].son[],mid+,r);
    return ;
}
 
void insert(int &x,int rot,int key,int l,int r) {
    if (!x) x=++tot;
    if (l==r) {
        t[x].cnt=t[rot].cnt+; return ;
    }
    int mid=l+r>>;
    if (key>mid) {
        t[x].son[]=t[rot].son[];
        insert(t[x].son[],t[rot].son[],key,mid+,r);
    } else {
        t[x].son[]=t[rot].son[];
        insert(t[x].son[],t[rot].son[],key,l,mid);
    }
    t[x].cnt=t[rot].cnt+;
    return ;
}
 
int query(int lx,int rx,int key,int l,int r) {
    //printf("%d %d %d\n",lx,rx,key);
    if (l==r) return l;
    int mid=l+r>>;
    if (t[t[rx].son[]].cnt-t[t[lx].son[]].cnt>key) return query(t[lx].son[],t[rx].son[],key,l,mid); else
    if (t[t[rx].son[]].cnt-t[t[lx].son[]].cnt>key) return query(t[lx].son[],t[rx].son[],key,mid+,r); else
        return ;
}
 
int main() {
    //freopen("kur.in","r",stdin); freopen("kur.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (int i=;i<=n;i++) scanf("%d",&a[i].key),a[i].num=i;
    sort(a+,a++n,cmp1);
    int j=; ans[]=a[].key;
    for (int i=,cur=a[].key;i<=n;i++)
        if (a[i].key==cur) a[i].key=j; else cur=a[i].key,a[i].key=++j,ans[j]=cur;
    //for (int i=1;i<=n;i++) printf("%d %d\n",a[i].num,a[i].key);
    sort(a+,a++n,cmp2);
    build(rot[],,j);
    for (int i=;i<=n;i++) insert(rot[i],rot[i-],a[i].key,,j);
    //for (int i=1;i<=tot;i++) printf("%d %d %d %d %d %d\n",i,t[i].left,t[i].right,t[i].son[0],t[i].son[1],t[i].cnt);
    while (m--) {
        int l,r; scanf("%d%d",&l,&r);
        if (l>r) swap(l,r);
        printf("%d\n",ans[query(rot[l-],rot[r],(r-l+)/,,j)]);
    }
    //fclose(stdin); fclose(stdout);
    return ;
}

学长给了一个随机算法,虽然参数改了不是T就是WA,还是觉得挺有纪念意义的= =。

//By BLADEVIL
#include <ctime>
#include <cstdio>
#include <vector>
#include <cstdlib>
#define maxn 500010
#define k 10 using namespace std; int n,m;
int a[maxn];
vector<int>rot[maxn]; int calc(int x,int y) {
int l=,r=rot[x].size()-;
int ans=;
while (l<=r) {
int mid=l+r>>;
//printf("%d %d %d\n",l,r,mid);
if (rot[x][mid]<=y) ans=mid,l=mid+; else r=mid-;
}
return ans;
} int judge(int x,int l,int r) {
int a1=calc(x,l),a2=calc(x,r);
int ans=a2-a1+;
if (rot[x][a1]!=l) ans--;
return ans;
} int main() {
//freopen("kur.in","r",stdin); freopen("kur.out","w",stdout);
srand((int)time(NULL));
/*
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++) rot[1].push_back(a[i]);
scanf("%d",&m);
printf("%d\n",calc(1,m));
return 0;
*/
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
for (int i=;i<=n;i++) rot[a[i]].push_back(i);
while (m--) {
int l,r; scanf("%d%d",&l,&r);
for (int i=;i<=k;i++) {
int cur=l+rand()%(r-l+);
if (judge(a[cur],l,r)>(r-l+)/) {
printf("%d\n",a[cur]); l=r=-;
break;
}
}
if (l!=-) printf("0\n");
}
fclose(stdin); fclose(stdout);
return ;
}

bzoj 3524 可持久化线段树的更多相关文章

  1. bzoj 3123 可持久化线段树启发式合并

    首先没有连边的操作的时候,我们可以用可持久化线段树来维护这棵树的信息,建立权值可持久化线段树,那么每个点继承父节点的线段树,当询问为x,y的时候我们可以询问rot[x]+rot[y]-rot[lca( ...

  2. bzoj 3207 可持久化线段树

    首先因为固定询问长度,所以我们可以将整个长度为n的数列hash成长度为n-k+1的数列,每次询问的序列也hash成一个数,然后询问这个数是不是在某个区间中出现过,这样我们可以根据初始数列的权值建立可持 ...

  3. bzoj 3207 可持久化线段树+hash

    这道题要看出来这个做法还是比较容易说一下细节 1.因为要用hash的区间值域来建树,而hash为了不冲突要开的很大,所以值域就会比较的大,不过这道题好的一点是没有修改,所以直接离散一下就会小很多 2. ...

  4. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

  5. 【BZOJ 3524】【Poi2014】Couriers 可持久化线段树

    为什么这个主席树叫可持久化线段树,我不知道,具体得问达神.我无限T,然后DaD3zZ一针见血地指出了我的N*50爆内存导致无限编译超时O)ZO)ZO)Z真是太神啦.以图为鉴: 达神题解传送门:http ...

  6. [BZOJ 3218] A + B Problem 【可持久化线段树 + 网络流】

    题目连接:BZOJ - 3218 题目分析 题目要求将 n 个点染成黑色或白色,那么我们可以转化为一个最小割模型. 我们规定一个点 i 最后属于 S 集表示染成黑色,属于 T 集表示染成白色,那么对于 ...

  7. [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】

    题目链接:BZOJ - 3207 题目分析 先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x . 这一步可以使用可持久化线段树来做,虽然感觉可以有更 ...

  8. BZOJ.4771.七彩树(可持久化线段树)

    BZOJ 考虑没有深度限制,对整棵子树询问怎么做. 对于同种颜色中DFS序相邻的两个点\(u,v\),在\(dfn[u],dfn[v]\)处分别\(+1\),\(dfn[LCA(u,v)]\)处\(- ...

  9. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

随机推荐

  1. [剑指Offer] 64.滑动窗口的最大值

    题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6 ...

  2. [剑指Offer] 58.对称的二叉树

    题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. [思路]递归,关键是isSame函数中的最后一句 /* struct Tree ...

  3. BZOJ 1103 大都市(dfs序+树状数组)

    应该是一道很水的题吧... 显然可以用树链剖分解决这个问题,虽然不知道多一个log会不会T.但是由于问题的特殊性. 每次修改都是将边权为1的边修改为0,且询问的是点i到根节点的路径长度. 令点i到根节 ...

  4. (四)Redis哈希表Hash操作

    Hash全部命令如下: hset key field value # 将哈希表key中的字段field的值设为value hget key field # 返回哈希表key中的字段field的值val ...

  5. CentOS expr和let

    1.expr,用于计算变量等 用法:expr 表达式 用例1: #运算符号和参数之间要有空格分开:[es@bigdata-senior01 ~]$ expr 2 + 3 5 #乘号(*)需要用 \ , ...

  6. 【刷题】洛谷 P2709 小B的询问

    题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...

  7. BZOJ 1016 Windy 数 | 数位DP

    题目: http://www.lydsy.com/JudgeOnline/problem.php?id=1026 题解: f[i][j][1/0]表示枚举到第i位,这位开头是j,当前的数大于(1)或小 ...

  8. [Ahoi2005]COMMON 约数研究 【欧拉线性筛的应用】

    1968: [Ahoi2005]COMMON 约数研究 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 2939  Solved: 2169 [Submi ...

  9. nowcoder OI 周赛 最后的晚餐(dinner) 解题报告

    最后的晚餐(dinner) 链接: https://www.nowcoder.com/acm/contest/219/B 来源:牛客网 题目描述 \(\tt{**YZ}\)(已被和谐)的食堂实在是太挤 ...

  10. 洛谷 P1311 选择客栈 解题报告

    P1311 选择客栈 题目描述 丽江河边有 \(n\) 家很有特色的客栈,客栈按照其位置顺序从 \(1\) 到 \(n\) 编号.每家客栈都按照某一种色调进行装饰(总共 \(k\) 种,用整数 \(0 ...