【刷题】BZOJ 1901 Zju2112 Dynamic Rankings

Description

给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。

Input

第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。
分别表示序列的长度和指令的个数。
第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。
接下来的m行描述每条指令
每行的格式是下面两种格式中的一种。
Q i j k 或者 C i t
Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)
表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。
C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t
m,n≤10000

Output

对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

Sample Input

5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3

Sample Output

3
6

Solution

这是一道树套树的题目,树状数组套主席树
从最基本的开始
找区间第\(k\)大,主席树
如果我们对于修改直接暴力做,那么正确性保证,但复杂度不能承受
那么我们就想什么东西可以帮助主席树维护动态的前缀和(静态的查询其实主席树自己就把前缀和做了),而查询第\(k\)大的事情还是由主席树做
于是我们就想到了BIT(树状数组)
常用的BIT可以支持单点修改求前缀和
那么我们把BIT的“点”变成主席树的“树”,就可以完成这道题了

#include<bits/stdc++.h>
#define ll long long
#define db double
#define ld long double
#define Mid ((l+r)>>1)
#define lson l,Mid
#define rson Mid+1,r
#define left 0
#define right 1
const int MAXN=10000+10;
int n,m,A[MAXN];
struct node{
	char opt;
	int i,j,k,t;
};
node Q[MAXN];
std::vector<int> V;
std::map<int,int> M;
struct ChairManTree_BIT{
	int cnt,lc[MAXN<<9],rc[MAXN<<9],num[MAXN<<9],root[MAXN],need[2][20],nt[2],size;
	inline void init()
	{
		cnt=0;
		memset(lc,0,sizeof(lc));
		memset(rc,0,sizeof(rc));
		memset(num,0,sizeof(num));
	}
	inline int lowbit(int x)
	{
		return x&(-x);
	}
	inline void Insert(int &rt,int l,int r,int pos,int val)
	{
		if(!rt)rt=++cnt;
		num[rt]+=val;
		if(l==r)return ;
		else
		{
			if(pos<=Mid)Insert(lc[rt],lson,pos,val);
			else Insert(rc[rt],rson,pos,val);
		}
	}
	inline void add(int x,int k,int p)
	{
		while(x<=n)
		{
			Insert(root[x],1,size,k,p);
			x+=lowbit(x);
		}
	}
	inline void Gneed(int nxt[])
	{
		for(register int i=1;i<=nt[left];++i)need[left][i]=nxt[need[left][i]];
		for(register int i=1;i<=nt[right];++i)need[right][i]=nxt[need[right][i]];
	}
	inline int Query(int l,int r,int k)
	{
		if(l==r)return l;
		else
		{
			int t=0;
			for(register int i=1;i<=nt[right];++i)t+=num[lc[need[right][i]]];
			for(register int i=1;i<=nt[left];++i)t-=num[lc[need[left][i]]];
			if(k<=t)
			{
				Gneed(lc);
				return Query(lson,k);
			}
			else
			{
				Gneed(rc);
				return Query(rson,k-t);
			}
		}
	}
	inline int sum(int l,int r,int k)
	{
		nt[left]=nt[right]=0;
		l--;
		while(l>0)
		{
			need[left][++nt[left]]=root[l];
			l-=lowbit(l);
		}
		while(r>0)
		{
			need[right][++nt[right]]=root[r];
			r-=lowbit(r);
		}
		return Query(1,size,k);
	}
};
ChairManTree_BIT T;
template<typename T> inline void read(T &x)
{
	T data=0,w=1;
	char ch=0;
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
	x=data*w;
}
template<typename T> inline void write(T x,char c='\0')
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
	if(c!='\0')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void newnum(int &x)
{
	int pre=x;
	x=lower_bound(V.begin(),V.end(),x)-V.begin()+1;
	M[x]=pre;
}
inline void discre()
{
	std::sort(V.begin(),V.end());
	V.erase(unique(V.begin(),V.end()),V.end());
	T.size=V.size();
	for(register int i=1;i<=n;++i)newnum(A[i]);
	for(register int i=1;i<=m;++i)
		if(Q[i].opt=='C')newnum(Q[i].t);
}
int main()
{
	read(n);read(m);
	for(register int i=1;i<=n;++i)
	{
		read(A[i]);
		V.push_back(A[i]);
	}
	for(register int i=1;i<=m;++i)
	{
		std::cin>>Q[i].opt;
		if(Q[i].opt=='Q')read(Q[i].i),read(Q[i].j),read(Q[i].k);
		else
		{
			read(Q[i].i),read(Q[i].t);
			V.push_back(Q[i].t);
		}
	}
	discre();
	T.init();
	for(register int i=1;i<=n;++i)T.add(i,A[i],1);
	for(register int i=1;i<=m;++i)
	{
		if(Q[i].opt=='Q')write(M[T.sum(Q[i].i,Q[i].j,Q[i].k)],'\n');
		if(Q[i].opt=='C')
		{
			T.add(Q[i].i,A[Q[i].i],-1);
			A[Q[i].i]=Q[i].t;
			T.add(Q[i].i,A[Q[i].i],1);
		}
	}
	return 0;
}

posted @ 2018-03-22 15:50  HYJ_cnyali  阅读(136)  评论(0编辑  收藏  举报