首先要知道 (m/1 + m/2 + ... + m/m) 约为 mlogm

还有一个比较明显的结论,如果一个纪念品区间长度大于d,那么如果列车的停车间隔小于等于d,则这个纪念品一定能被买到

然后把区间按长度排序

枚举d,边枚举边加那些长度小于d的区间到线段树当中,这样可以保证一个纪念品不会被加2次

最后输出答案即可

#include <iostream>
#include <algorithm>
using namespace std;
const int Maxn = *;
namespace seqtree
{
struct Tree
{
Tree *ch[];
long long _v, label;
int Num, _l, _r, mid;
Tree() { _v = label = ; Num = ; }
void update();
void maintain();
}Node[Maxn], *null, *Root;
int tot = , _k, _L, _R;
long long v;
void Tree::update()
{
if(!label) return;
_v += Num*label;
if(Num != ) ch[]->label += label, ch[]->label += label;
label = ;
}
void Tree::maintain()
{
ch[]->update(); ch[]->update();
_v = ch[]->_v + ch[]->_v;
}
void protect()
{
null = new Tree();
null->ch[] = null->ch[] = null; null->Num = ;
}
void insert(Tree *&o, int l, int r)
{
int mid = (l+r)/;
if(o == null)
{
o = &Node[tot++];
o->ch[] = o->ch[] = null;
o->_l = l; o->_r = r; o->mid = (l+r)/;
}
if(l == r) { o->_v = v; return; }
if(_k <= mid) insert(o->ch[], l, mid);
else insert(o->ch[], mid+, r);
o->maintain(); o->Num = o->ch[]->Num + o->ch[]->Num;
}
Tree* Build(int n, long long *a)
{
protect(); Root = null;
for(int i = ; i <= n; i++) _k = i, v = a[i], insert(Root, , n);
return Root;
}
long long query(Tree *o)
{
long long ans = ;
o->update();
if(_L <= o->_l && o->_r <= _R) return o->_v;
if(_L <= o->mid) ans += query(o->ch[]);
if(_R > o->mid) ans += query(o->ch[]);
return ans;
}
long long Query(int L, int R) { _L = L; _R = R; return query(Root); }
void change(Tree *o)
{
o->update();
if(_L <= o->_l && o->_r <= _R) { o->label += v; o->update(); return; }
if(_L <= o->mid) change(o->ch[]); if(_R > o->mid) change(o->ch[]);
o->maintain();
}
void Change(int L, int R, int V) { _L = L; _R = R; v = V; change(Root); }
};
using namespace seqtree; struct Data
{
int l, r, v;
bool operator < (const Data &B) const
{ return v < B.v; }
}A[Maxn]; int n, m, l, r;
long long a[Maxn], ANS[Maxn];
int main()
{
cin.sync_with_stdio(false);
cin>>n>>m;
Build(m+, a);
for(int i = ; i < n; i++)
{
cin>>A[i].l>>A[i].r;
A[i].v = A[i].r - A[i].l + ;
}
sort(A, A+n);
int k = ;
for(int i = ; i <= m; i++)
{
for(; A[k].v < i && k < n; k++) Change(A[k].l, A[k].r, );
int ans = n - k;
for(int j = i; j <= m; j += i) ans += Query(j, j);
cout<<ans<<endl;
}
}

最新文章

  1. IntelliMVCCode智能MVC架构的代码助手使用方法
  2. Jquery请求Ajax的json数据
  3. gulp学习笔记2-安装
  4. 【转】Android自定义View的实现方法,带你一步步深入了解View(四)
  5. DBHelper数据库操作类(二)
  6. GeoServer基础教程(一):环境搭建篇
  7. JavaWeb:基于MVC设计模式的一个小案例(一)
  8. (转)Ubuntu中让终端对于历史输出的内容保持足够长
  9. Android核心基础(十一)
  10. 通过改变viewport 实现网站自适应
  11. 基于均值漂移的三维网格分割算法(Mean Shift)
  12. C#中的匿名函数使用,类名&lt;T&gt;
  13. CentOS 7 Shell脚本编程第九讲 read命令简单介绍
  14. momentjs 学习
  15. AI 循环神经网络
  16. BZOJ4946 NOI2017蔬菜(贪心+堆)
  17. 简单题(K-D Tree)
  18. flume1.8实现hdfsSink整点滚动文件
  19. JQuery使用教程
  20. vue中兄弟之间组件通信

热门文章

  1. (转)Maven POM中的各种scope的行为总结
  2. jquery图片滚动normalizy.css
  3. JavaScript -- 继承与原型链
  4. 什么是token及怎样生成token
  5. centOS下yum报错
  6. ruby 数据类型Symbol
  7. STL 一些常用的STL函数(持续更新
  8. 三角形xjoi 8.14
  9. app:showAsAction 和android:showAsAction
  10. xss挑战赛小记 0x01(xsstest)