萌新求助,调了3个小时了(有注释)
查看原帖
萌新求助,调了3个小时了(有注释)
65190
_LanFeng_楼主2021/7/25 13:07
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+10;
struct Node
{
    int l,r;
}a[N];
int n,k;
int f[N][21],ans=1000000000;
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-f;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-48;s=getchar();}
    return x*f;
}
bool cmp(Node a,Node b)
{
    return a.l<b.l;
}
int main()
{
    n=read(),k=read();
    for(int i=1;i<=k;i++)
    {
    	a[i].l=read(),a[i].r=read();
    	if(a[i].l>a[i].r) a[i].r+=n;
	}
    sort(a+1,a+k+1,cmp);
    for(int i=1,j=1,Max=0;i<=n;i++)//找最大值
    {
        while(j<=k&&a[j].l<=i) 
        {
        	Max=max(Max,a[j].r);
        	j++;
		}
		if(Max>=i)
        f[i][0]=Max+1;//f区间左必右开
    }
    int x=1,S=0;
    for(int i=20;i>=0;i--)
    if(f[x][i]&&f[x][i]<=n) 
    {
        x=f[x][i];
        S+=(1<<i);
    }
    if(f[x][0]>n) ans=min(ans,S+1);//先判断不用跨越这个圈的线段
    for(int j=1;j<=20;j++) 
    for(int i=1;i<=n;i++) 
	f[i][j]=f[f[i][j-1]][j-1];
    for(int i=1;i<=k;i++)//在枚举跨越圈的线段
    if(a[i].r>n)
	{
		int sum=0,s=a[i].r-n+1;
		for(int j=20;j>=0;j--)
		{
			if(f[s][j]&&f[s][j]<a[i].l)
			{
				sum+=(1<<j);
				s=f[s][j];
			}
		}
		if(f[s][0]>=a[i].l)
		ans=min(ans,sum+2);
	 } 
    if (ans==1000000000) printf("impossible");
	else printf("%d",ans);
    return 0;
}
2021/7/25 13:07
加载中...