ARC068E Snuke Line

Posted cjoiershiina-mashiro

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARC068E Snuke Line相关的知识,希望对你有一定的参考价值。

Link
假设现在枚举的列车是隔(d)站停一次车。
那么对于所有长度(ge d)的区间,一定会在这个区间中停至少一次车。
对于所有长度(<d)的区间,最多在这个区间中停一次车。
因此我们可以先把所有区间按区间长度升序排序,然后从小到大枚举停车间隔(d),把所有区间长度(=d-1)的加进树状数组,然后枚举倍数查询总共停了多少个区间,再加上所有(ge d)的区间个数就行了。

#include<cstdio>
#include<cctype>
#include<algorithm>
const int N=300007,M=100007;
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
struct node{int l,r;}a[N];
int n,m,ans[M],t[M];
void add(int p,int v){for(;p<=m;p+=p&-p)t[p]+=v;}
void upd(int l,int r){add(l,1);if(r<m)add(r+1,-1);}
int ask(int p){int s=0;for(;p;p^=p&-p)s+=t[p];return s;}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;++i) a[i].l=read(),a[i].r=read();
    std::sort(a+1,a+n+1,[](node&a,node&b){return a.r-a.l<b.r-b.l;});
    for(int i=1,p=1,s;i<=m;++i)
    {
    for(s=0;p<=n&&a[p].r-a[p].l<i;++p) upd(a[p].l,a[p].r);
    for(int j=i;j<=m;j+=i) s+=ask(j);
    printf("%d
",n-p+1+s);
    }
}

以上是关于ARC068E Snuke Line的主要内容,如果未能解决你的问题,请参考以下文章

做题arc068_e-Snuke Line——利用特殊性质分讨

問題の解決策 ARC099 D - Snuke Numbers

ARC078 D.Fennec VS. Snuke(树上博弈)

[ARC061E]すぬけ君の地下鉄旅行 / Snuke's Subway Trip

AtCoder ARC061E Snuke's Subway Trip 最短路

luogu AT2300 Snuke Line |树状数组