http://poj.org/problem?id=2104
今天入门半年的ACM辣鸡终于搞懂了主席树
其实主席树也没有那么难
以前一直学不会大概是没有意志把它学下去
或者说是内心比较浮躁
总是看不下去别人的blog
下边的一个板子是我从网上找的比较漂亮的一个板子
当然我自己是写不出来的
明天来学习带修改的主席树
好像要附加上树状数组
如果可以单位时间访问每个节点的话
其实可以在查询的时候直接二分
当然了树状结构的查询思想也是基于二分的
我知道我写的博客可能别人都不懂
因为我的博客是写给我自己看的
在博客上留下我大学生活的记忆
自己的大学生话是充实的
不管结果如何
坚持的在acm这一天坑里走下去
AC代码:
#include<iostream>
#include<vector>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=1e5+6;
int n,m,cnt=0,root[maxn],a[maxn],x,y,k;
struct node{
int l,r,sum;
}T[maxn*40];
vector<int>v;
int getid(int x){/
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void update(int l,int r,int &x,int y,int pos){
T[++cnt]=T[y],T[cnt].sum++,x=cnt;
if(l==r) return ;
int mid=(l+r)/2;
if(mid>=pos) update(l,mid,T[x].l,T[y].l,pos);
else update(mid+1,r,T[x].r,T[y].r,pos);
}
int query(int l,int r,int x,int y,int k){
if(l==r) return l;
int mid=(l+r)/2;
int sum=T[T[y].l].sum-T[T[x].l].sum;
if(sum>=k) return query(l,mid,T[x].l,T[y].l,k);
else return query(mid+1,r,T[x].r,T[y].r,k-sum);
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),v.push_back(a[i]);
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
for(int i=1;i<=n;i++) update(1,n,root[i],root[i-1],getid(a[i]));
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&k);
printf("%d\n",v[query(1,n,root[x-1],root[y],k)-1]);
}
}