线段树专题2-(加强版线段树-可持续化线段树)主席树 orz! ------用于解决区间第k大的问题----xdoj-1216
poj-2104(区间第K大问题)
- #include <iostream>
- #include <algorithm>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- struct T {
- int ls;
- int rs;
- int sum;
- };
- const int N=1e5+;
- T tri[*N];
- int a[N],sort_a[N];
- int rt[N];
- int cnt;
- int n,m;
- void update (int l,int r,int rt1,int &rt2,int pos) {
- rt2=++cnt;
- tri[rt2]=tri[rt1];
- tri[rt2].sum++;// 在此处直接更新,就不用pushup了
- if (l==r) return ;
- int mid=(l+r)/;
- if (pos<=mid) update (l,mid,tri[rt1].ls,tri[rt2].ls,pos);
- else update (mid+,r,tri[rt1].rs,tri[rt2].rs,pos);
- return ;
- }
- int query (int l,int r,int rt1,int rt2,int k) {
- if (l==r) return sort_a[l];
- int mid=(l+r)/;
- int sum=tri[tri[rt2].ls].sum-tri[tri[rt1].ls].sum;//我又出错了 sum应该是左子树的节点数 T_T !
- if (k<=sum) return query (l,mid,tri[rt1].ls,tri[rt2].ls,k);
- else return query (mid+,r,tri[rt1].rs,tri[rt2].rs,k-sum);
- }
- int main ()
- {
- scanf ("%d %d",&n,&m);
- for (int i=;i<=n;i++) {
- scanf ("%d",&a[i]);
- sort_a[i]=a[i];
- }
- sort (sort_a+,sort_a++n);
- int num=;
- for (int i=;i<=n;i++) {
- if (sort_a[i]!=sort_a[i-])
- sort_a[++num]=sort_a[i];//离散化
- }
- rt[]=cnt=;
- tri[].sum=tri[].ls=tri[].rs=;
- for (int i=;i<=n;i++) {
- int pos=lower_bound (sort_a+,sort_a++num,a[i])-sort_a;
- update (,num,rt[i-],rt[i],pos);
- }
- for (int i=;i<=m;i++) {
- int x,y,k;
- scanf ("%d %d %d",&x,&y,&k);
- printf("%d\n",query (,num,rt[x-],rt[y],k));
- }
- return ;
- }
NO.2 HDOJ-4417(主席数的区间求和)
- #include<cstdio>
- #include<algorithm>
- const int N=1e5+;
- using namespace std;
- struct node {
- int ls;
- int rs;
- int sum;
- };
- node tri[*N];
- int rt[N];
- int a[N],sort_a[N+];
- int cnt,n,m,x,y,k;
- void updata (int l,int r,int rt1,int& rt2,int pos) {
- rt2=(++cnt);
- tri[rt2]=tri[rt1];
- tri[rt2].sum++;
- if (l==r) return ;
- int mid=(l+r)/;
- if (pos<=mid) updata(l,mid,tri[rt1].ls,tri[rt2].ls,pos);
- else updata(mid+,r,tri[rt1].rs,tri[rt2].rs,pos);
- return ;
- }
- int query (int l,int r,int L,int R,int rt1,int rt2) {
- if (r<L||l>R) return ;
- if (l>=L&&r<=R) return tri[rt2].sum-tri[rt1].sum;
- int mid=(l+r)/;
- int t1=query(l,mid,L,R,tri[rt1].ls,tri[rt2].ls);
- int t2=query(mid+,r,L,R,tri[rt1].rs,tri[rt2].rs);
- return t1+t2;
- }
- int main ()
- {
- int T;
- int tt=;
- scanf ("%d",&T);
- while (T--) {
- printf("Case %d:\n",tt++);
- scanf ("%d %d",&n,&m);
- for (int i=;i<=n;i++) {
- scanf ("%d",&a[i]);
- sort_a[i]=a[i];
- }
- sort(sort_a+,sort_a++n);
- int num=;
- for (int i=;i<=n;i++) {
- if (sort_a[i]!=sort_a[num])
- sort_a[++num]=sort_a[i];
- }
- cnt=;
- rt[]=;
- tri[].ls=tri[].rs=tri[].sum=;
- for (int i=;i<=n;i++) {
- int pos=lower_bound(sort_a+,sort_a++num,a[i])-sort_a;
- updata(,num,rt[i-],rt[i],pos);
- }
- for (int i=;i<=m;i++) {
- scanf ("%d %d %d",&x,&y,&k);
- int t=lower_bound(sort_a+,sort_a++num,k)-sort_a;
- if (t>num||sort_a[t]>k) t--;// 这个好 找最后一个小于等于k的数
- int ans=query (,num,,t,rt[x],rt[y+]);// 因为题目从0开始计数
- printf("%d\n",ans);
- }
- }
- return ;
- }
No.3 xdoj-1216(子树第k小)——dfs+主席树
- #include<cstdio>
- #include<algorithm>
- #include<vector>
- using namespace std;
- const int N=1e5+;
- struct T{
- int ls;
- int rs;
- int sum;
- };
- vector < vector <int> > g(N);
- T tri[N*];
- int rt[N],b[N],sort_b[N];
- int in[N],out[N];
- int val[N];
- int cnt,num;
- int n,q;
- int x,k;
- void dfs (int id,int pre) {
- num++;
- sort_b[num]=b[num]=val[id];
- in[id]=num;
- for (int i=;i<g[id].size();i++) {
- int next=g[id][i];
- if (next==pre) continue;
- dfs (next,id);
- }
- out[id]=num;
- }
- void updata (int l,int r,int pos,int rt1,int& rt2) {
- cnt++;
- rt2=cnt;
- tri[cnt]=tri[rt1];
- tri[cnt].sum++;
- if (l==r) return ;
- int mid=(l+r)/;
- if (pos<=mid) updata (l,mid,pos,tri[rt1].ls,tri[rt2].ls);
- else updata (mid+,r,pos,tri[rt1].rs,tri[rt2].rs);
- return ;
- }
- int query (int l,int r,int k,int rt1,int rt2) {
- if (l==r) return l;
- int mid=(l+r)/;
- int ans;
- int sum=tri[tri[rt2].ls].sum-tri[tri[rt1].ls].sum;
- if (k<=sum) ans=query (l,mid,k,tri[rt1].ls,tri[rt2].ls);
- else ans=query (mid+,r,k-sum,tri[rt1].rs,tri[rt2].rs);
- return ans;
- }
- int main ()
- {
- while (scanf ("%d",&n)!=EOF) {
- for (int i=;i<=n;i++) g[i].clear();
- for (int i=;i<=n;i++)
- scanf ("%d",&val[i]);
- int u,v;
- for (int i=;i<=n-;i++) {
- scanf ("%d %d",&u,&v);
- g[u].push_back(v);
- g[v].push_back(u);
- }
- num=;
- dfs (,-);// 按理说有根树 直接dfs(1)就可以了可是这样答案是不对的 是我理解错了还是数据有问题呢
- sort(sort_b+,sort_b++n);
- int nn=;
- for (int i=;i<=n;i++)
- if (sort_b[i]!=sort_b[nn])
- sort_b[++nn]=sort_b[i];
- rt[]=;
- tri[].rs=tri[].ls=tri[].sum=;
- cnt=;
- for (int i=;i<=n;i++) {
- int pos=lower_bound(sort_b+,sort_b++nn,b[i])-sort_b;
- updata(,nn,pos,rt[i-],rt[i]);
- }
- scanf ("%d",&q);
- for (int i=;i<=q;i++) {
- scanf ("%d %d",&x,&k);
- int ans=query (,nn,k,rt[in[x]-],rt[out[x]]);
- printf ("%d\n",sort_b[ans]);
- }
- }
- return ;
- }
线段树专题2-(加强版线段树-可持续化线段树)主席树 orz! ------用于解决区间第k大的问题----xdoj-1216的更多相关文章
- POJ 2104 HDU 2665 主席树 解决区间第K大
两道题都是区间第K大询问,数据规模基本相同. 解决这种问题, 可以采用平方划分(块状表)复杂度也可以接受,但是实际表现比主席树差得多. 这里大致讲一下我对主席树的理解. 首先,如果对于某个区间[L,R ...
- 可持久化线段树(主席树)(图文并茂详解)【poj2104】【区间第k大】
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=63740442 向大(hei)佬(e)实力学(di ...
- Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)(值域线段树第k大)
Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序 ...
- 可持久化线段树(主席树)——静态区间第k大
主席树基本操作:静态区间第k大 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=2e5+, ...
- 【BZOJ3551】Peaks加强版(Kruskal重构树,主席树)
[BZOJ3551]Peaks加强版(Kruskal重构树,主席树) 题面 BZOJ Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相 ...
- 主席树入门(区间第k大)
主席树入门 时隔5个月,我又来填主席树的坑了,现在才发现学算法真的要懂了之后,再自己调试,慢慢写出来,如果不懂,就只会按照代码敲,是不会有任何提升的,都不如不照着敲. 所以搞算法一定要弄清原理,和代码 ...
- 【ZOJ2112】【整体二分+树状数组】带修改区间第k大
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
- POJ2104-- K-th Number(主席树静态区间第k大)
[转载]一篇还算可以的文章,关于可持久化线段树http://finaltheory.info/?p=249 无修改的区间第K大 我们先考虑简化的问题:我们要询问整个区间内的第K大.这样我们对值域建线段 ...
- hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)
题目链接 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2 ...
随机推荐
- Find a way out of the ClassLoader maze
June 6, 2003 Q: When should I use Thread.getContextClassLoader() ? A: Although not frequently asked, ...
- etymon word flower bee apiary forget out~1
1● anth 2● flower 花 1● ap 2● bee 3● apiary 养殖场
- vs2015如何使用附加进程调试发布在IIS上项目
1.如何使用附加进程调试IIS上的网站项目 1)在IIS部署一个网站项目 2)保证浏览器可访问(比如访问登陆页面) 3)在项目中LoginController断点,并在工具栏的调试找到附加到进程 4) ...
- laravel在控制器中动态创建数据表
Schema::connection('usertable')->create('test', function ($table) { $table->increments('id'); ...
- Win10系列:UWP界面布局基础8
路由事件 XAML不仅继承了传统的事件处理方式,还引入了一个增强型事件处理机制:路由事件(RoutedEvent).路由事件和传统事件的不同是:路由事件允许一个对象触发事件后,可以同时拥有多个事件接收 ...
- Java 方法重载 方法重写
方法重载规则 参数个数不同 参数个数相同,但参数列表中对应的某个参数的类型不一样 方法的返回类型和参数名称不参与重载 "编译期绑定",,因为未产生对象,只看参数.引用类型绑定方法 ...
- [HDU3436]Queue-jumpers
Problem 有一个数列,从1排列到n,然后有Q个操作 Top x:将第x个数放到序列的最前面 Query x:询问x这个数在第几位 Rank x:询问第x位数是什么 Solution n非常的大, ...
- IIS设置上传文件大小限制
单位为字节. 500*1024*1024=524288000
- 关于collectionview布局的坑
不知道写了多少次collectionview,步了很多坑,现在看来虽然达到了自己想要的结果,却不知道其中所以然.还是总结一下,免得再走弯路: 场景是这样的,我要定制一个显示选择图片的排列,想要实现横向 ...
- linux文件查看
查看目录 #查看文件 使用 ls 命令,加上参数 -l 表示查看详细信息,-a 表示查看包含隐藏文件在内的文件.也可使用通配符,*代表任意个字符,? 表示单个字符. $ ls ch*.doc #表 ...