正题
题目链接:
https://www.luogu.com.cn/problem/AT2300
https://atcoder.jp/contests/arc068/tasks/arc068_c
题目大意
有mmm个车站,nnn种礼品,第iii种可以在[li,ri][l_i,r_i][li,ri]的车站买到,第ddd辆车会近过编号为ddd的倍数的车站,对于每个ddd最多能买到多少件礼物。
解题思路
考虑对于一组[L,R][L,R][L,R]能否买到礼物ddd,我们不难发现需要满足条件⌊L−1d⌋≠⌊Rd⌋\lfloor\frac{L-1}{d}\rfloor\neq\lfloor\frac{R}{d}\rfloor⌊dL−1⌋=⌊dR⌋即可。
学习了莫比乌斯反演的话不难发现对于⌊L−1d⌋\lfloor\frac{L-1}{d}\rfloor⌊dL−1⌋和⌊Rd⌋\lfloor\frac{R}{d}\rfloor⌊dR⌋只有不超过2(L−1+R)2(\sqrt {L-1}+\sqrt R)2(L−1+R)种取值,而对于相同的取值的ddd一定是一个区间。
我们进行整除分块,然后用差分进行区间加,时间复杂度O(nm+m)O(n\sqrt m+m)O(nm+m)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int m,n,a[101000];
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){int L,R,l,r;scanf("%d%d",&L,&R);L--;for(l=1;l<=L;l=r+1){r=min(L/(L/l),R/(R/l));if(L/l!=R/l)a[l]++,a[r+1]--;}a[l]++;a[R+1]--;}for(int i=1;i<=m;i++){a[i]+=a[i-1];printf("%d\n",a[i]);}
}