把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

luogu P3730 曼哈顿交易

题面传送门
显然可以莫队,而且是板子题。
但是考虑怎么在过程中增加和修改,无论怎样写树形结构都会使复杂度飙升到\(n\sqrt nlogn\)
这时可以暴力数据结构:分块,单点修改\(O(1)\),查询\(O(\sqrt n)\)
这样复杂度就是妥妥的\(O(n\sqrt n)\)
代码实现:

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,k,x,y,z,nows[100039],tots[100039],a[100039],l,r,mid,ans[100039],st[100039],fs[100039],ku[1039];
struct yyy{int x,y,z,num;}f[100039],tmp;
inline bool cmp(yyy x,yyy y){return ((x.x/k==y.x/k)?(((x.x/k)&1)?x.y<y.y:x.y>y.y):x.x<y.x);}
inline void read(int &x){
	char s=getchar();x=0;
	while(s<'0'||s>'9') s=getchar();
	while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+(s^48),s=getchar();
}
int main(){
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	register int i,j,h;
	scanf("%d%d",&n,&m);
	k=sqrt(n);
	for(i=1;i<=n;i++) read(a[i]),nows[i]=a[i];
	for(i=1;i<=m;i++) read(f[i].x),read(f[i].y),read(f[i].z),f[i].num=i;
	sort(nows+1,nows+n+1);
	for(i=1;i<=n;i++){
		tots[i]=tots[i-1];
		if(nows[i]!=nows[i-1]) tots[i]++;
	}
	for(i=1;i<=n;i++){
		l=0;r=n+1;
		while(l+1<r){
			mid=(l+r)>>1;
			if(nows[mid]<a[i]) l=mid;
			else r=mid;
		}
		a[i]=tots[r];
	}
	sort(f+1,f+m+1,cmp);
	l=1;r=0;
	for(i=1;i<=m;i++){
		tmp=f[i];
		while(l>tmp.x){
			l--;
			if(st[a[l]])ku[st[a[l]]/k]--,fs[st[a[l]]]--;
			st[a[l]]++;
			fs[st[a[l]]]++;
			ku[st[a[l]]/k]++;
		}
		while(r<tmp.y){
			r++;
			if(st[a[r]])ku[st[a[r]]/k]--,fs[st[a[r]]]--;
			st[a[r]]++;
			fs[st[a[r]]]++;
			ku[st[a[r]]/k]++;
			//printf("%d %d %d\n",r,fs[st[a[r]]],ku[st[a[r]]/k]);
		}
		while(l<tmp.x){
			ku[st[a[l]]/k]--;
			fs[st[a[l]]]--;
			st[a[l]]--;
			if(st[a[l]])fs[st[a[l]]]++,ku[st[a[l]]/k]++;
			l++;
		}
		while(r>tmp.y){
			ku[st[a[r]]/k]--;
			fs[st[a[r]]]--;
			st[a[r]]--;
			if(st[a[r]])fs[st[a[r]]]++,ku[st[a[r]]/k]++;
			r--;
		}
		ans[tmp.num]=-1;
		for(j=0;j<=n/k;j++){
			//printf("%d\n",fs[0]);
			if(tmp.z>ku[j]) tmp.z-=ku[j];
			else{
				for(h=j*k;h<j*k+k;h++) {
					if(tmp.z>fs[h]) tmp.z-=fs[h];
					else {ans[tmp.num]=h;break;}
				}
				break;
			}
		}
	}
	for(i=1;i<=m;i++) printf("%d\n",ans[i]);
}
posted @ 2020-07-10 21:56  275307894a  阅读(38)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end