• 题解 可怜的狗狗


    P1533 可怜的狗狗

    更好阅读体验

    题意:

    小卡家有N只狗,由于品种、年龄不同,每一只狗都有一个不同的漂亮值;
    漂亮值与漂亮的程度成反比(漂亮值越低越漂亮),吃饭时,狗狗们会
    按顺序站成一排等着主人给食物。可是嘉嘉真的很懒,他才不肯喂这么多狗呢,
    这多浪费时间啊,于是他每次就只给第i只到第j只狗中第k漂亮的狗狗喂食(好
    狠心的人啊).而且为了保证某一只狗狗不会被喂太多次,他喂的每个区间(i,j)不互相包含;

    思路:因为要找的是排名第k的,考虑主席树和平衡树;

    不会平衡树的点这里哦
    由于刚学平衡树,这里提供平衡树思路,以为有很多区间,不可能
    把上一次全删掉再一个一个加,T飞?
    考虑莫队的思想,这题可以用莫队(不过我不会),可以把询问离线,拍下序,每次把
    上下两次区间重复的就不用删除了,有大佬直接过了,可我常数大,不过吸个氧跑很快的;

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=3e5+7;
    struct node{
    	int ff,val,siz,cnt,ch[2];
    }t[N];
    struct quary{
    	int l,r,k,id;
    	friend bool operator <(const quary &x,const quary &y){
    		return x.r<y.r;
    	}
    }q[N<<1];
    int n,m,tot,root;
    int a[N],ans[N];
    
    void up(int x){
    	t[x].siz=t[x].cnt+t[t[x].ch[0]].siz+t[t[x].ch[1]].siz;
    } 
    
    void rotate(int x){
    	int y=t[x].ff;
    	int z=t[y].ff;
    	int k=t[y].ch[1]==x;
    	t[z].ch[t[z].ch[1]==y]=x;
    	t[x].ff=z;
    	t[y].ch[k]=t[x].ch[k^1];
    	t[t[x].ch[k^1]].ff=y;
    	t[x].ch[k^1]=y;
    	t[y].ff=x;
    	up(y);up(x);
    }
    
    void splay(int x,int goal){
    	while(t[x].ff!=goal){
    		int y=t[x].ff,z=t[y].ff;
    		if(z!=goal) (t[z].ch[0]==y)^(t[y].ch[0]==x)?rotate(x):rotate(y);
    		rotate(x);
    	}
    	if(goal==0) root=x;
    }
    
    void insert(int x){
    	int u=root,ff=0;
    	while(u&&t[u].val!=x){
    		ff=u;
    		u=t[u].ch[x>t[u].val];
    	}
    	if(u) t[u].cnt++;
    	else{
    		u=++tot;
    		if(ff) t[ff].ch[x>t[ff].val]=u;
    		t[u].siz=t[u].cnt=1;
    		t[u].ff=ff;
    		t[u].val=x;
    	}
    	splay(u,0);
    }
    
    void find(int x){
    	int u=root;
    	if(!u) return;
    	while(t[u].ch[x>t[u].val]&&t[u].val!=x){
    		u=t[u].ch[x>t[u].val];
    	}
    	splay(u,0);
    }
    
    int Nxt(int x,int f){
    	find(x);
    	int u=root;
    	if(x<t[u].val&&f) return u;
    	if(x>t[u].val&&!f) return u;
    	u=t[u].ch[f];
    	while(t[u].ch[f^1]) u=t[u].ch[f^1];
    	return u; 
    }
    
    void Del(int x){
    	int last=Nxt(x,0);
    	int nxt=Nxt(x,1);
    	splay(last,0);
    	splay(nxt,last);
    	int del=t[nxt].ch[0];
    	if(t[del].cnt>1){
    		t[del].cnt--;
    		splay(del,0);
    	}else t[nxt].ch[0]=0,t[nxt].siz--,t[last].siz--;
    }
    
    int k_th(int x){
    	int u=root;
    	if(t[u].siz<x) return 0;
    	while(1){
    		int y=t[u].ch[0];
    		if(t[y].siz+t[u].cnt<x){
    			x-=t[y].siz+t[u].cnt;
    			u=t[u].ch[1];
    		}else{
    			if(x<=t[y].siz) u=y;
    			else return t[u].val;
    		}
    	}
    }
    
    int main(){
    	insert(-2147483647);
    	insert(2147483647);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
    		q[i].id=i;
    	}
    	sort(q+1,q+m+1);
    	int x=q[1].l,y=q[1].r;
    	for(int i=q[1].l;i<=q[1].r;i++) insert(a[i]);
    	ans[q[1].id]=k_th(q[1].k+1);
    	for(int i=2;i<=m;i++){
    		while(x<q[i].l) Del(a[x]),x++;
    		while(y>q[i].r) Del[a[y]],y--;
    		while(x>q[i].l) x--,insert(a[x]);
    		while(y<q[i].r) y++,insert(a[y]);
    //		cout<<x<<" "<<y<<" "<<q[i].k<<"
    ";
    		ans[q[i].id]=k_th(q[i].k+1);
    	}
    	for(int i=1;i<=m;i++){
    		cout<<ans[i]<<"
    ";
    	}
    }
    
  • 相关阅读:
    中间件(1)分布式缓存
    大型网站架构演进(9)服务化
    大型网站架构演进(8)业务拆分
    大型网站架构演进(7)数据库拆分
    大型网站架构演进(6)使用NoSQL和搜索引擎
    大型网站架构演进(5)数据库读写分离
    大型网站架构演进(4)使用应用服务器集群
    大型网站架构演进(3)使用缓存改善网站性能
    大型网站架构演进(2)数据库与应用服务器分离
    大型网站架构演进(1)单机网站
  • 原文地址:https://www.cnblogs.com/Aswert/p/13619730.html
Copyright © 2020-2023  润新知