zoukankan      html  css  js  c++  java
  • CF702F T-Shirts

    题面

    英文题面

    题意:

    题解:考虑枚举每个物品,用数据结构来维护人。先将物品按(v_i)递减排序,用平衡树来维护人。设当前枚举到了物品(i),那么所有平衡树内权值大于等于(v_i)的节点的权值都要减去(v_i),然后答案(+1),但这样会破坏平衡树的二叉搜索树的性质。

    考虑权值在([v_i+1,2v_i])的节点会破坏性质,我们就将这些点删除,然后一个一个暴力插回平衡树里。由于这些点的权值都至少减半,每个点只会被这样操作(log_B)次。所以复杂度是正确的。

    建议使用fhq-treap。注意最后求答案时要将打的标记全部下传。

    时间复杂度:(O(nlogm+mlogmlogB))

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define re register int
    #define F(x,y,z) for(re x=y;x<=z;x++)
    #define FOR(x,y,z) for(re x=y;x>=z;x--)
    typedef long long ll;
    #define I inline void
    #define IN inline int
    #define C(x,y) memset(x,y,sizeof(x))
    #define STS system("pause")
    template<class D>I read(D &res){
    	res=0;register D g=1;register char ch=getchar();
    	while(!isdigit(ch)){
    		if(ch=='-')g=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch)){
    		res=(res<<3)+(res<<1)+(ch^48);
    		ch=getchar();
    	}
    	res*=g;
    }
    mt19937 _rnd(time(0));
    struct P{
    	int c,w;
    	friend bool operator < (P x,P y){
    		return x.w==y.w?x.c<y.c:x.w>y.w;
    	}
    }p[202000];
    int n,m,a[202000],sa[202000],rk[202000],ans[202000];
    int root,ch[202000][2],siz[202000],rnd[202000],laz[202000],tag[202000];
    inline bool bbb(int x,int y){return a[x]<a[y];}
    I push_up(int x){
    	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
    }
    I build(int &k,int l,int r){
    	if(l>r)return;
    	k=(l+r)>>1;siz[k]=1;rnd[k]=_rnd();
    	build(ch[k][0],l,k-1);build(ch[k][1],k+1,r);
    	push_up(k);
    }
    I add(int k,int val,int num){
    	laz[k]+=val;a[k]-=val;ans[k]+=num;tag[k]+=num;
    }
    I push_down(int x){
    	if(ch[x][0])add(ch[x][0],laz[x],tag[x]);
    	if(ch[x][1])add(ch[x][1],laz[x],tag[x]);
    	laz[x]=tag[x]=0;
    }
    I split(int now,int k,int &x,int &y){
    	if(!now)return x=y=0,void();
    	if(laz[now])push_down(now);
    	if(a[now]<=k){
    		x=now;split(ch[x][1],k,ch[x][1],y);push_up(x);
    	}
    	else{
    		y=now;split(ch[y][0],k,x,ch[y][0]);push_up(y);
    	}
    }
    IN merge(int x,int y){
    	if(!x||!y)return x+y;
    	if(laz[x])push_down(x);if(laz[y])push_down(y);
    	if(rnd[x]<rnd[y]){
    		ch[x][1]=merge(ch[x][1],y);push_up(x);return x;
    	}
    	else{
    		ch[y][0]=merge(x,ch[y][0]);push_up(y);return y;
    	}
    }
    I damage(int x){
    	if(laz[x])push_down(x);
    	if(ch[x][0])damage(ch[x][0]);
    	if(ch[x][1])damage(ch[x][1]);
    	ch[x][0]=ch[x][1]=0;siz[x]=1;rnd[x]=_rnd();
    	re X,Y;split(root,a[x]-1,X,Y);
    	root=merge(merge(X,x),Y);
    }
    I getans(int x){
    	if(laz[x])push_down(x);
    	if(ch[x][0])getans(ch[x][0]);
    	if(ch[x][1])getans(ch[x][1]);
    }
    int main(){
    	read(m);
    	F(i,1,m)read(p[i].c),read(p[i].w);sort(p+1,p+1+m);
    	read(n);F(i,1,n)read(a[i]),sa[i]=i;
    	sort(sa+1,sa+1+n,bbb);F(i,1,n)rk[sa[i]]=i;
    	sort(a+1,a+1+n);build(root,1,n);
    	re X,Y,Z;
    	F(i,1,m){
    		split(root,p[i].c-1,X,Y);add(Y,p[i].c,1);split(Y,p[i].c,Y,Z);root=merge(X,Z);
    		damage(Y);
    	}
    	getans(root);
    	F(i,1,n)printf("%d ",ans[rk[i]]);
    	return 0;
    }
    /*
    3
    7 5
    3 5
    4 3
    2
    13 14
    2
    100 500
    50 499
    4
    50 200 150 100
    */
    
  • 相关阅读:
    Spring Security OAuth2 源码分析
    Spring Security OAuth2 token权限隔离
    Spring Cloud Feign 使用OAuth2
    Spring Security OAuth2 授权码模式
    全链路追踪spring-cloud-sleuth-zipkin
    Spring Security OAuth2 授权失败(401) 问题整理
    使用ShardingJdbc分表
    Kubectl常用命令
    Spring Cloud Zuul实现IP访问控制
    一次非核心接口(信息提示类)被刷引发的思考
  • 原文地址:https://www.cnblogs.com/Purple-wzy/p/13308144.html
Copyright © 2011-2022 走看看