arc068 E: Snuke Line

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

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

然后把区间按长度排序

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

最后输出答案即可

#include <iostream>
#include <algorithm>
using namespace std;
const int Maxn = 4*111111;
namespace seqtree
{
    struct Tree
    {
        Tree *ch[2];
        long long _v, label;
        int Num, _l, _r, mid;
        Tree() { _v = label = 0; Num = 1; }
        void update();
        void maintain();
    }Node[Maxn], *null, *Root;
    int tot = 0, _k, _L, _R;
    long long v;
    void Tree::update()
    {
        if(!label) return;
        _v += Num*label;
        if(Num != 1) ch[0]->label += label, ch[1]->label += label;
        label = 0;
    }
    void Tree::maintain()
    {
        ch[0]->update(); ch[1]->update();
          _v = ch[0]->_v + ch[1]->_v;
    }
    void protect()
    {
       null = new Tree();
       null->ch[0] = null->ch[1] = null; null->Num = 0;
    }
    void insert(Tree *&o, int l, int r)
    {
        int mid = (l+r)/2;
        if(o == null)
        {
             o = &Node[tot++];
             o->ch[0] = o->ch[1] = null;
             o->_l = l; o->_r = r; o->mid = (l+r)/2;
        }
        if(l == r) { o->_v = v; return; }
        if(_k <= mid) insert(o->ch[0], l, mid);
        else insert(o->ch[1], mid+1, r);
        o->maintain(); o->Num = o->ch[1]->Num + o->ch[0]->Num;
    }
    Tree* Build(int n, long long *a)
    {
          protect(); Root = null;
           for(int i = 1; i <= n; i++) _k = i, v = a[i], insert(Root, 1, n);
           return Root;
    }
    long long query(Tree *o)
    {
        long long ans = 0;
        o->update();
        if(_L <= o->_l && o->_r <= _R) return o->_v;
        if(_L <= o->mid) ans += query(o->ch[0]);
        if(_R > o->mid) ans += query(o->ch[1]);
        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[0]);   if(_R > o->mid) change(o->ch[1]);
      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+1, a);
    for(int i = 0; i < n; i++)
    {
        cin>>A[i].l>>A[i].r;
        A[i].v = A[i].r - A[i].l + 1;
    }
    sort(A, A+n);
    int k = 0;
    for(int i = 1; i <= m; i++)
    {
        for(; A[k].v < i && k < n; k++)  Change(A[k].l, A[k].r, 1);
        int ans = n - k;
        for(int j = i; j <= m; j += i) ans += Query(j, j);
        cout<<ans<<endl;
    }
}
时间: 2024-08-03 20:32:23

arc068 E: Snuke Line的相关文章

[arc086e]snuke line

题意: 有n个区间,询问对于$1\leq i\leq m$的每个i,有多少个区间至少包含一个i的倍数? $1\leq N\leq 3\times 10^5$ $1\leq M\leq 10^5$ 题解: 开始就想到了调和级数的复杂度,但是一直没想到反着统计... 正着统计区间是否包含$i$的倍数很麻烦,不妨反过来统计是否不包含,那么不包含的情况肯定是区间卡在两个$i$的倍数之间或者在$\lfloor\frac{m}{i}\rfloor\times i$和$M$之间,那么可以将询问离线,按照$i$

luogu AT2300 Snuke Line |树状数组

有一趟列车有 M+1 个车站,从 0 到 M 编号.有 N 种商品,第 i 种只在编号 [li,ri] 的车站出售.一辆列车有一个预设好的系数 d,从 0 出发,只会在 d 的倍数车站停车.对于 d 从 1 到 M 的列车,求最多能买到多少种商品. 把区间放进树状数组里,logn查询 但是长区间可能会算重复,所以先把长度区间小于d的区间放进去 长度大于等于d的必定会有交,所以直接统计答案 #include<cstdio> #include<cstring> #include<

一些数据结构杂题简要题解

[POI2015] Kinoman 二维数点问题,常用套路是,枚举其中一个端点,然后维护到每个端点的区间的值. 设一部电影上一个播放日为 \(pre_i\),下一个播放日为 \(nxt_i\),发现每场电影 \(i\) 只有在 \(l > pre_i,r<nxt_i\) 的区间中对答案有贡献. 所以我们先将所有区间按照 \(pre_i\) 从小到大排序,从左到右枚举左端点,维护一棵以右端点为下标的线段树,每次将 \(pre_i<l\) 的点在区间 \([i,nxt_i)\) 加入贡献,并

すぬけ君の塗り絵 / Snuke&#39;s Coloring AtCoder - 2068 (思维,排序,贡献)

Problem Statement We have a grid with H rows and W columns. At first, all cells were painted white. Snuke painted N of these cells. The i-th ( 1≤i≤N ) cell he painted is the cell at the ai-th row and bi-th column. Compute the following: For each inte

R:incomplete final line found by readTableHeader on

报错: In read.table("abc.txt", header = T) :  incomplete final line found by readTableHeader on 'abc.txt' 解决方法: 在数据文件abc.txt最后一行加上回车即可解决.

windows git安装后更换the line ending conversions

Is there a file or menu that will let me change the settings on how to deal with line endings? There are 3 options: Checkout Windows-style, commit Unix-style line endings Git will convert LF to CRLF when checking out text files. When committing text

hdu 5691 Sitting in Line

传送门 Sitting in Line Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 293    Accepted Submission(s): 143 Problem Description 度度熊是他同时代中最伟大的数学家,一切数字都要听命于他.现在,又到了度度熊和他的数字仆人们玩排排坐游戏的时候了.游戏的规则十分简单,参与

error: bad top line in state file /var/lib/logrotate.status 解决方法

发现日志切割并没有按计划执行,后来手动强制执行时,发现如下报错: [[email protected] logrotate.d]# logrotate -f httpd error: bad top line in state file /var/lib/logrotate.status [[email protected] logrotate.d]# 解决访求: 删除/var/lib/logrotate.status 这个文件即可解决. 解决后,最好再运行一下logrotate -f /etc

OpenCV Tutorials &mdash;&mdash; Hough Line Transform

霍夫直线变换 -- 用于检测图像中的直线 利用图像空间和Hough参数空间的点--直线对偶性,把图像空间中的检测问题转换到参数空间,通过在参数空间进行简单的累加统计,然后在Hough参数空间中寻找累加器峰值的方法检测直线 Standard and Probabilistic Hough Line Transform OpenCV implements two kind of Hough Line Transforms: The Standard Hough Transform It consis