• 【BZOJ4444】【SCOI2015】—国旗计划(倍增+贪心)


    传送门

    有点有趣的一道题

    先拆环为链并倍长

    发现由于路径之前没有覆盖关系
    所以对于一条路径,接下来走的下一条是一定的,贪心选最远的那一条
    那对于每一条路径的下一条可以在O(n)O(n)求出来的

    考虑倍增f[i][j]f[i][j]表示从ii开始走2j2^j条路径会走到哪里
    然后对于每个人暴力跳一下看多久跳到mm就可以了

    复杂度O(nlogn)O(nlogn)

    据说有O(n)O(n)做法?

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    #define int unsigned int 
    const int N=400005;
    int f[N][22],n,m,q[N],l,r,ans[N];
    struct node{
    	int l,r,id;
    	friend inline bool operator <(const node &a,const node &b){
    		return a.r<b.r;
    	}
    }p[N];
    signed main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++){
    		p[i].l=read(),p[i].r=read();
    		if(p[i].l>p[i].r)p[i].r+=m;
    		p[i].id=i,p[i+n]=p[i],p[i+n].l+=m,p[i+n].r+=m;
    	}
    	sort(p+1,p+n*2+1);
    	f[2*n][0]=n*2,q[l=r=1]=n*2;
    	for(int i=2*n-1;i;i--){
    		while(p[q[l]].l>p[i].r)l++;
    		f[i][0]=q[l];q[++r]=i;
    	}
    	for(int j=1;j<=19;j++){
    		for(int i=1;i<=n*2;i++){
    			f[i][j]=f[f[i][j-1]][j-1];
    		}
    	}
    	for(int i=1;i<=n;i++){
    		int x=i,l=p[i].l,id=p[i].id;
    		for(int j=19;~j;j--){
    			if(p[f[x][j]].r-l<m)
    				x=f[x][j],ans[id]+=(1<<j);
    		}
    		ans[id]+=2;
    	}
    	for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
    }
    
  • 相关阅读:
    大搜车知乎live中的面试题结题方法记录
    git 学习笔记
    JavaScript 函数节流和函数去抖应用场景辨析
    要不要用gzip优化前端项目
    js和native交互方法浅析
    js设计模式之惰性单例模式
    阻止a标签的默认事件及延伸
    为什么会有OPTIONS请求
    浅析前端渲染与服务端渲染
    exports 和 module.exports 的区别
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145595.html
Copyright © 2020-2023  润新知