0
点赞
收藏
分享

微信扫一扫

AtCoder Regular Contest 068 E - Snuke Line(好题:思维+树状数组 )

Xin_So 2023-02-08 阅读 54


E - Snuke Line

Time Limit: 2 sec / Memory Limit: 256 MB

Score : 700700 points

Problem Statement

Snuke has decided to play a game, where the player runs a railway company. There are M+1M+1 stations on Snuke Line, numbered 00 through MM. A train on Snuke Line stops at station 00 and every dd-th station thereafter, where dd is a predetermined constant for each train. For example, if d=3d=3, the train stops at station 00, 33, 66, 99, and so forth.

There are NN kinds of souvenirs sold in areas around Snuke Line. The ii-th kind of souvenirs can be purchased when the train stops at one of the following stations: stations lili, li+1li+1, li+2li+2, ......, riri.

There are MM values of dd, the interval between two stops, for trains on Snuke Line: 11, 22, 33, ......, MM. For each of these MM values, find the number of the kinds of souvenirs that can be purchased if one takes a train with that value of dd at station 00. Here, assume that it is not allowed to change trains.

Constraints

  • 1≦N≦3×1051≦N≦3×105
  • 1≦M≦1051≦M≦105
  • 1≦li≦ri≦M1≦li≦ri≦M

Input

The input is given from Standard Input in the following format:


NN MM l1l1 r1r1 :: lNlN rNrN


Output

Print the answer in MM lines. The ii-th line should contain the maximum number of the kinds of souvenirs that can be purchased if one takes a train stopping every ii-th station.

Sample Input 1 Copy

Copy


3 3
1 2
2 3
3 3


Sample Output 1 Copy

Copy

3
2
2


  • If one takes a train stopping every station, three kinds of souvenirs can be purchased: kind 11, 22 and 33.
  • If one takes a train stopping every second station, two kinds of souvenirs can be purchased: kind 11 and 22.
  • If one takes a train stopping every third station, two kinds of souvenirs can be purchased: kind 22 and 33.

Sample Input 2 Copy

Copy


7 9
1 7
5 9
5 7
5 9
1 1
6 8
3 4


Sample Output 2 Copy

Copy


7
6
6
5
4
5
5
3
2


题意:

 M+1 个车站(0 ~ M 编号)。 N 种商品,第 i 种只在编号 [li,ri] 的车站出售。

求对于每一个 d,从 0 出发,只会在 d 的倍数车站停车。对于 d 从 1 到 M 的列车,求最多能买到多少种商品。

分析:

我们需要思想:

我们来考虑对于每一个d,会有多少种商品无法购买。

车子停下来点集:(0,d,2d,3d,.....kd)(kd<=m)。

我们可以知道无法购买的商品i,必定满足其(li,ri)在上述点集某两个相邻点之间,即可以购买的商品,必然会跨过若干个点。

即得到核心性质:对于d,所有ri-li>=d的i都是可以购买的。

所有我们把所有商品按ri-li的大小排序,对于ri-li>=d的直接加上;其他商品,由于ri-li<d,它们最多跨过一个点,则我们只需要枚举跨过某个点的商品个数总和,树状数组实现前缀和。

#include <bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
#define PI acos(-1.0)
#define MOD 2520
#define E 1e-12
using namespace std;
typedef long long ll;
const int MAXN=500000+5;//最大元素个数
int n,m;//元素个数
int c[MAXN];//c[i]==A[i]+A[i-1]+...+A[i-lowbit(i)+1]
//返回i的二进制最右边1的值
int lowbit(int i)
{
return i&(-i);
}
//返回A[1]+...A[i]的和
int sum(int x)
{
int sum = 0;
while(x)
{
sum += c[x];
x -= lowbit(x);
}
return sum;
}
//令A[i] += val
void add(int x, int val)
{

while(x <= n) //注意这里的n,是树状数组维护的长度
{
c[x] += val;
x += lowbit(x);
}
}
struct node
{
int l,r;
}a[MAXN];
bool cmp(node x,node y)
{
return x.r-x.l<y.r-y.l;
}

int main()
{

while(scanf("%d%d",&m,&n)!=-1)
{
memset(c,0,sizeof(c));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
}
sort(a+1,a+m+1,cmp);

int j=0;
for(int d=1;d<=n;d++)
{
int temp=0;
for(int i=d;i<=n;i+=d)//计算以前区间跨过一个点的个数
{
temp+=sum(i);
}
//m-j表示ri-li>=d的商品数量
printf("%d\n",temp+m-j);

while(j<m&&a[j+1].r-a[j+1].l<=d)//最多可能跨过一个点的商品数量记录到树状数组上
{
add(a[j+1].l,1);
add(a[j+1].r+1,-1);
j++;
}

}
}
return 0;
}

举报

相关推荐

0 条评论