zoukankan      html  css  js  c++  java
  • 【CF1523G】Try Booking

    题目

    题目链接:https://codeforces.com/problemset/problem/1523/G
    William 想在之后的 (n) 天内出租他的公寓。有 (m) 个请求待 William 依次处理,对于第 (i) 个请求 ([l_i,r_i]) 表示一人想在 ([l_i,r_i]) 天内租借公寓,而这个请求会被接受当且仅当 (r_i-l_i+1ge x)([l_i,r_i]) 这些天内公寓都是空闲的。请对每个 (x=1cdots n) 输出公寓出租的总天数。
    (nle 5 imes 10^4, mle 10^5, 1le l_ile r_ile n)

    思路

    不难发现,对于每一个 (x),同意的请求数量的上界是 (lfloorfrac{n}{x} floor),所以对于 (x=1cdots n),同意的请求数量总数是 (O(nlog n)) 的。
    考虑一个很 naive 的做法,对于每一个 (x),我们依次枚举所有请求,如果这个请求可以接受,那么相当于剩余可以被使用的时间分成了两个区间,继续往后枚举解决。
    也就是有一个可以使用的时间区间 ([L,R])(初始时为 ([1,n])),我们寻找编号最小的,(r_i-l_i+1geq x),且 (Lleq l_i,r_ileq R) 间的请求 (i),通过这个请求,递归 ([L,l_i),(r_i,R]) 这两个区间继续。
    如果我们倒序枚举 (x),相当于需要支持加入新的点 ((l,r)),查询一个子矩阵的编号最小的点。可以用树状数组套线段树解决。
    又由于总共通过的请求数量是 (O(nlog n)) 的,所以操作次数也是 (O(nlog n)) 的,时间复杂度为 (O(nlog^3 n+mlog^2 n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=100010,LG=16,Inf=1e9;
    int n,m,rt[N],ans[N],L[N],R[N],id[N];
    
    bool cmp(int x,int y)
    {
    	return R[x]-L[x]>R[y]-L[y];
    }
    
    struct SegTree
    {
    	int tot,minn[N*LG*4],lc[N*LG*4],rc[N*LG*4];
    	SegTree() { memset(minn,0x3f3f3f3f,sizeof(minn)); }
    	
    	int update(int x,int l,int r,int k,int v)
    	{
    		if (!x) x=++tot;
    		minn[x]=min(minn[x],v);
    		if (l==r) return x;
    		int mid=(l+r)>>1;
    		if (k<=mid) lc[x]=update(lc[x],l,mid,k,v);
    			else rc[x]=update(rc[x],mid+1,r,k,v);
    		return x;
    	}
    	
    	int query(int x,int l,int r,int ql,int qr)
    	{
    		if (!x) return Inf;
    		if (ql<=l && qr>=r) return minn[x];
    		int mid=(l+r)>>1,res=Inf;
    		if (ql<=mid) res=min(res,query(lc[x],l,mid,ql,qr));
    		if (qr>mid) res=min(res,query(rc[x],mid+1,r,ql,qr));
    		return res;
    	}
    }seg;
    
    struct BIT
    {
    	void add(int x,int p,int v)
    	{
    		for (int i=x;i<=n;i+=i&-i)
    			rt[i]=seg.update(rt[i],1,n,p,v);
    	}
    	
    	int query(int x,int p)
    	{
    		int ans=Inf;
    		for (int i=x;i;i-=i&-i)
    			ans=min(ans,seg.query(rt[i],1,n,p,n));
    		return ans;
    	}
    }bit;
    
    int solve(int l,int r)
    {
    	int id=bit.query(r,l);
    	if (id>=Inf) return 0;
    	return solve(l,L[id]-1)+solve(R[id]+1,r)+R[id]-L[id]+1;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=m;i++)
    	{
    		scanf("%d%d",&L[i],&R[i]);
    		id[i]=i;
    	}
    	sort(id+1,id+1+m,cmp);
    	for (int i=n,j=1;i>=1;i--)
    	{
    		for (;j<=m && R[id[j]]-L[id[j]]+1>=i;j++)
    			bit.add(R[id[j]],L[id[j]],id[j]);
    		ans[i]=solve(1,n);
    	}
    	for (int i=1;i<=n;i++) cout<<ans[i]<<"
    ";
    	return 0;
    }
    
  • 相关阅读:
    1.27
    1.25
    Representation Learning with Contrastive Predictive Coding
    Learning a Similarity Metric Discriminatively, with Application to Face Verification
    噪声对比估计(负样本采样)
    Certified Adversarial Robustness via Randomized Smoothing
    Certified Robustness to Adversarial Examples with Differential Privacy
    Dynamic Routing Between Capsules
    Defending Adversarial Attacks by Correcting logits
    Visualizing Data using t-SNE
  • 原文地址:https://www.cnblogs.com/stoorz/p/14893685.html
Copyright © 2011-2022 走看看