例5T了,求助
查看原帖
例5T了,求助
1049051
JiuZhE66666楼主2023/10/9 20:39
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll s[400005][20]={0};
struct warrior
{
    ll r;
    ll l;
    ll id;
    bool operator<(const warrior b) const{return l<b.l;}
}solder[900005];
int main()
{
    ll n,m;
    scanf("%lld%lld",&n,&m);
    for(ll i=1;i<=n;i++)
        {
            scanf("%lld%              lld",&solder[i].l,&solder[i].r);
            if(solder[i].r<solder[i].l)solder[i].r+=m;
          //  solder[i+n+n].l=solder[i+n].l+m;
          //  solder[i+n+n].r=solder[i+n].r+m;
            solder[i].id=i;
        }
       // printf("\n");


    sort(solder+1,solder+n+1);
    for(ll i=1;i<=n;i++)
    {
        solder[i+n]=solder[i];
        solder[i+n].l=solder[i].l+m;
        solder[i+n].r=solder[i].r+m;
    }

   // sort(solder+n+2+n,solder+2*n+n+1);
    //for(int i=1;i<=2*n;i++)printf("%d个人的左点:%d,右点: %d \n",i,solder[i].l,solder[i].r);//拆环成链看看效果

    for(ll i=1;i<=2*n;i++)
    {
        ll t=i+1;
        while(solder[t].l<=solder[i].r&&t<=2*n)t++;
        s[i][0]=t-1;
    }//找到下一个最远传递人

    for(ll i=1;(1<<i)<=n;i++)
        for(ll j=1;j<=2*n;j++)
    {
        s[j][i]=s[s[j][i-1]][i-1];
    }//倍增法,找到第2,4,8个最远传递人
    //printf("\n");


    /*for(int i=0;(1<<i)<=n;i++)
    {
        for(int j=1;j<=2*n;j++)
        {
            printf("%d的第%d个最远传递人是:%d \n",j,1<<i,s[j][i]);
        }
        printf("\n");
    }//看看传递人对不对
    printf("\n");
*/
    int res[200005]={0};
    for(int i=1;i<=n;i++)
    {
        int t=i,sum=0;
        for(int j=log(n)/log(2);j>=0;j--)
        {
            if(solder[s[t][j]].r<solder[i+n].l&&s[t][j])//
            {
                //printf("%d\n",j);
                sum+=(1<<j);
                t=s[t][j];
                //printf("%d\n",sum);
            }
            //if(solder[t].r<solder[i+n].l&&)
        }
        res[solder[i].id]=sum+2;
    }
    for(int i=1;i<=n;i++)
    {
        printf("%d ",res[i]);
    }
    return 0;
}
2023/10/9 20:39
加载中...