• 「SCOI2015」国旗计划 解题报告


    「SCOI2015」国旗计划

    蛮有趣的一个题

    注意到区间互不交错,那么如果我们已经钦定了一个区间,它选择的下一个区间是唯一的,就是和它有交且右端点在最右边的,这个可以单调队列预处理一下

    然后往后面跳拿倍增优化一下


    Code:

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define int unsigned int
    const int N=4e5+10;
    template <class T>
    void read(T &x)
    {
    	x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    }
    int n,m,ans[N],q[N],l,r,f[N][20];
    struct yuucute
    {
    	int l,r,id;
    	bool friend operator <(yuucute a,yuucute b){return a.r<b.r;}
    }yuu[N];
    signed main()
    {
    	read(n),read(m);
    	for(int i=1;i<=n;i++)
    	{
    		read(yuu[i].l),read(yuu[i].r);
    		if(yuu[i].r<yuu[i].l) yuu[i].r+=m;
    		yuu[i].id=i;
    		yuu[i+n]=yuu[i];
    		yuu[i+n].l+=m,yuu[i+n].r+=m;
    	}
    	std::sort(yuu+1,yuu+1+(n<<1));
    	f[n<<1][0]=n<<1,q[l=r=1]=n<<1;
    	for(int i=(n<<1)-1;i;i--)
    	{
    		while(yuu[q[l]].l>yuu[i].r) ++l;
    		f[i][0]=q[l];
    		q[++r]=i;
    	}
    	for(int j=1;j<=19;j++)
    		for(int i=1;i<=n<<1;i++)
    			f[i][j]=f[f[i][j-1]][j-1];
    	for(int i=1;i<=n;i++)
    	{
    		int x=i,l=yuu[i].l,id=yuu[i].id;
    		for(int j=19;~j;j--)
    			if(yuu[f[x][j]].r-l<m)
    				x=f[x][j],ans[id]|=1<<j;
            ans[id]+=2;
    	}
    	for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    	return 0;
    }
    

    2019.3.3

  • 相关阅读:
    IntelliJ Idea 快捷键列表
    mysql索引类型和方式
    基本git指令
    idea中deBug方法
    BeanUtils.copyProperties(A,B)使用注意事项
    MySQL字段类型
    JAVA常识1
    Redis在windows下的安装下载
    Netty
    IDEA工具
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10467234.html
Copyright © 2020-2023  润新知