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;
}