区间第K大:POJ-2104
#include
#include
#include
#include
using namespace std;
const int maxn=1e5+1000;
int cnt,root[maxn],n,m;
int a[maxn];
vector v;
struct node
{
int l,r,sum;
}tree[maxn*40];
int getid(int x)
{
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void insert(int l,int r,int &x,int y,int pos)
{
tree[++cnt]=tree[y];tree[cnt].sum++,x=cnt;
if(l==r) return ;
int m=(l+r)>>1;
if(pos<=m) insert(l,m,tree[x].l,tree[y].l,pos);
else insert(m+1,r,tree[x].r,tree[y].r,pos);
}
int query(int l,int r,int x,int y,int k)
{
if(l==r) return l;
int m=(l+r)>>1;
int sum=tree[tree[y].l].sum-tree[tree[x].l].sum;
if(sum>=k){
return query(l,m,tree[x].l,tree[y].l,k);
}
else return query(m+1,r,tree[x].r,tree[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());
int sz=v.size();
for(int i=1;i<=n;i++) insert(1,sz,root[i],root[i-1],getid(a[i]));
while(m--)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
printf("%d\n",v[query(1,sz,root[x-1],root[y],k)-1]);
}
return 0;
}
树上第K小:SPOJ-COT
#include
using namespace std;
const int maxn=1e5+1000;
int a[maxn];
struct node
{
int l,r,sum;
}tree[maxn*40];
int cnt,root[maxn];
vector v[maxn],v1;
int num[maxn],fa[maxn][30],depth[maxn];
int n,m,sz;
int getid(int x){
return lower_bound(v1.begin(),v1.end(),x)-v1.begin()+1;
}
//void build(int l,int r,int &rt)
//{
// rt=++cnt;
// tree[rt].sum=0;
// if(l==r) return ;
// int m=(l+r)>>1;
// build(l,m,tree[rt].l);
// build(m+1,r,tree[rt].r);
//}
void update(int l,int r,int &x,int y,int pos){
tree[++cnt]=tree[y];tree[cnt].sum++;x=cnt;
if(l==r) return ;
int m=(l+r)>>1;
if(pos<=m) update(l,m,tree[x].l,tree[y].l,pos);
else update(m+1,r,tree[x].r,tree[y].r,pos);
}
int query(int l,int r,int x,int y,int z,int w,int k){
if(l==r) return l;
int m=(l+r)>>1;
int tmp=tree[tree[x].l].sum+tree[tree[y].l].sum-tree[tree[z].l].sum-tree[tree[w].l].sum;
if(tmpdepth[b]) swap(a,b);
int f=depth[b]-depth[a];
for(int j=0;(1<=0;i--){
if(fa[a][i]!=fa[b][i]){
a=fa[a][i],b=fa[b][i];
}
}
return fa[a][0];
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),v1.push_back(a[i]);
sort(v1.begin(),v1.end());
v1.erase(unique(v1.begin(),v1.end()),v1.end());
for(int i=1;i
区间不同值:SPOJ - DQUERY
#include
using namespace std;
const int maxn=1e5+100;
int root[maxn],cnt;
struct node
{
int l,r,num;
}tree[maxn*40];
int a[maxn];
map ma;
int sz=maxn;
void insert(int l,int r,int &x,int y,int pos,int v)
{
tree[++cnt]=tree[y];tree[cnt].num+=v;x=cnt;
if(l==r) return ;
int m=(l+r)>>1;
if(pos<=m) insert(l,m,tree[x].l,tree[y].l,pos,v);
else insert(m+1,r,tree[x].r,tree[y].r,pos,v);
}
int query(int l,int r,int L,int R,int y)
{
if(L<=l&&r<=R) return tree[y].num;
int m=(l+r)>>1;
int ans=0;
if(L<=m) ans+=query(l,m,L,R,tree[y].l);
if(R>m) ans+=query(m+1,r,L,R,tree[y].r);
return ans;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
if(ma[a[i]]==0){
insert(1,sz,root[i],root[i-1],i,1);//在第i个位置插入 保证线段树上区间也对应
ma[a[i]]=i;
}
else{
insert(1,sz,root[i],root[i-1],ma[a[i]],-1);
ma[a[i]]=i;
insert(1,sz,root[i],root[i],i,1);
}
}
int m;
cin>>m;
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",query(1,sz,x,y,root[y]));//0-root[y]即可
}
return 0;
}
区间第k大+区间不同值:HDU - 5919
#include
#include
#include
#include
主席树区间更新:HDU - 4348
#include
#include
#include
#include
using namespace std;
const int maxn=1e5+1000;
typedef long long ll;
int a[maxn];
struct node
{
int l,r;
ll sum,lazy;
}tree[maxn*40];
int root[maxn],tot;
int n,m;
int sz=maxn;
void build(int l,int r,int &x)
{
x=++tot;
tree[x].sum=0;
tree[x].lazy=0;
if(l==r)
{
tree[x].sum+=a[l];
return ;
}
int m=(l+r)>>1;
build(l,m,tree[x].l);
build(m+1,r,tree[x].r);
tree[x].sum=tree[tree[x].l].sum+tree[tree[x].r].sum;
}
void update(int l,int r,int L,int R,int &x,int y,int val)
{
x=++tot;
tree[x]=tree[y];
tree[x].sum+=1ll*val*(min(R,r)-max(l,L)+1);
if(L<=l&&r<=R){
tree[x].lazy+=val;
return ;
}
int m=(l+r)>>1;
if(L<=m) update(l,m,L,R,tree[x].l,tree[y].l,val);
if(R>m) update(m+1,r,L,R,tree[x].r,tree[y].r,val);
}
ll query(int l,int r,int L,int R,int x,ll lazy)
{
if(L<=l&&r<=R){
return tree[x].sum+lazy*(r-l+1);
}
ll ans=0;
int m=(l+r)>>1;
if(L<=m) ans+=query(l,m,L,R,tree[x].l,lazy+tree[x].lazy);
if(R>m) ans+=query(m+1,r,L,R,tree[x].r,lazy+tree[x].lazy);
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
tot=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int p=0;
build(1,sz,root[p]);
while(m--)
{
char op[10];
scanf("%s",op);
if(op[0]=='Q'){
int l,r;
scanf("%d%d",&l,&r);
printf("%lld\n",query(1,sz,l,r,root[p],0));
}
else if(op[0]=='C'){
int l,r,d;
scanf("%d%d%d",&l,&r,&d);
update(1,sz,l,r,root[p+1],root[p],d);
p++;
}
else if(op[0]=='B'){
int t;
scanf("%d",&t);
p=t;
}
else if(op[0]=='H'){
int l,r,t;
scanf("%d%d%d",&l,&r,&t);
printf("%lld\n",query(1,sz,l,r,root[t],0));
}
}
}
return 0;
}