bzoj 3524 可持久化线段树
我们可以先离散化,然后建立权值的可持久化线段树,记录每个数出现的次数,对于区间询问直接判断左右儿子的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 可持久化线段树的更多相关文章
- bzoj 3123 可持久化线段树启发式合并
首先没有连边的操作的时候,我们可以用可持久化线段树来维护这棵树的信息,建立权值可持久化线段树,那么每个点继承父节点的线段树,当询问为x,y的时候我们可以询问rot[x]+rot[y]-rot[lca( ...
- bzoj 3207 可持久化线段树
首先因为固定询问长度,所以我们可以将整个长度为n的数列hash成长度为n-k+1的数列,每次询问的序列也hash成一个数,然后询问这个数是不是在某个区间中出现过,这样我们可以根据初始数列的权值建立可持 ...
- bzoj 3207 可持久化线段树+hash
这道题要看出来这个做法还是比较容易说一下细节 1.因为要用hash的区间值域来建树,而hash为了不冲突要开的很大,所以值域就会比较的大,不过这道题好的一点是没有修改,所以直接离散一下就会小很多 2. ...
- 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 ...
- 【BZOJ 3524】【Poi2014】Couriers 可持久化线段树
为什么这个主席树叫可持久化线段树,我不知道,具体得问达神.我无限T,然后DaD3zZ一针见血地指出了我的N*50爆内存导致无限编译超时O)ZO)ZO)Z真是太神啦.以图为鉴: 达神题解传送门:http ...
- [BZOJ 3218] A + B Problem 【可持久化线段树 + 网络流】
题目连接:BZOJ - 3218 题目分析 题目要求将 n 个点染成黑色或白色,那么我们可以转化为一个最小割模型. 我们规定一个点 i 最后属于 S 集表示染成黑色,属于 T 集表示染成白色,那么对于 ...
- [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】
题目链接:BZOJ - 3207 题目分析 先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x . 这一步可以使用可持久化线段树来做,虽然感觉可以有更 ...
- BZOJ.4771.七彩树(可持久化线段树)
BZOJ 考虑没有深度限制,对整棵子树询问怎么做. 对于同种颜色中DFS序相邻的两个点\(u,v\),在\(dfn[u],dfn[v]\)处分别\(+1\),\(dfn[LCA(u,v)]\)处\(- ...
- BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)
BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...
随机推荐
- java面试95题
1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注 ...
- Thinkphp5图片、音频和视频文件上传
首先是同步上传,最为基础的上传的方式,点击表单提交之后跳转那种.如下前端代码 <!DOCTYPE html> <html lang="en"> <he ...
- Qt Meta Object system 学习
原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...
- arp获取
getarp.c /* getarp.c -- This simple program uses an IOCTL socket call to read an entry */ /* from th ...
- servlet的service特性就是http协议的特性 即连接完就断开
servlet的service特性就是http协议的特性 即连接完就断开
- 2011 Multi-University Training Contest 8 - Host by HUST
Rank:56/147. 开场看B,是个线段树区间合并,花了2hour敲完代码...再花了30min查错..发现push_down有问题.改了就AC了. 然后发现A过了很多人.推了个公式,发现是个分段 ...
- 【bzoj1507】[NOI2003]Editor /【bzoj1269】[AHOI2006]文本编辑器editor Splay
[bzoj1507][NOI2003]Editor 题目描述 输入 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中 ...
- hdu5696区间的价值 -- 2016"百度之星" - 初赛(Astar Round2B)
Problem Description 我们定义“区间的价值”为一段区间的最大值*最小值. 一个区间左端点在L,右端点在R,那么该区间的长度为(R−L+1). 现在聪明的杰西想要知道,对于长度为k的区 ...
- 【题解】CF#983 E-NN country
首先,我们从 u -> v 有一个明显的贪心,即能向上跳的时候尽量向深度最浅的节点跳.这个我们可以用树上倍增来维护.我们可以认为 u 贪心向上跳后不超过 lca 能跳到 u' 的位置, v 跳到 ...
- 【BZOJ4894】天赋(矩阵树定理)
[BZOJ4894]天赋(矩阵树定理) 题面 BZOJ Description 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有 一些天赋必须是要有 ...