Description:
m
m
个区间,对于每个,每
d
d
个位置插一个点,问每个被多少个区间覆盖。
Solution:
按照区间长度排序,小于间隔的最多覆盖一个点,那么树状数组差分解决,大于的肯定覆盖。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 5;
int n, m;
int t[maxn];
struct data {
int l, r, len;
bool friend operator < (const data &a, const data &b) {
return a.len < b.len;
}
} a[maxn];
void add(int p, int d) {
for(; p <= m; p += p & -p) {
t[p] += d;
}
}
int query(int p) {
int ret = 0;
for(; p; p -= p & -p) {
ret += t[p];
}
return ret;
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
scanf("%d%d", &a[i].l, &a[i].r);
a[i].len = a[i].r - a[i].l + 1;
}
sort(a + 1, a + n + 1);
for(int i = 1, j = 1; i <= m; ++i) {
while(j <= n && a[j].len < i) {
add(a[j].l, 1);
add(a[j].r + 1, -1);
++j;
}
int ans = n - j + 1;
for(int j = i; j <= m; j += i) {
ans += query(j);
}
printf("%d\n", ans);
}
return 0;
}