zoukankan      html  css  js  c++  java
  • [arc068E]Snuke Line-[树状数组]

    Description

    传送门

    Solution

    假如想直接YY对于每一个d会有多少种商品满足条件,em反正我搞不定。

    然后大佬的题解告诉我说:搞不定?那就不搞它啊,反过来不就得了?

    好吧。我们来考虑对于每一个d,会有多少种商品无法购买。

    我们目前有一些点,组成的集合为(0,d,2d,3d,.....kd)(kd<=m),车子会在这些点停下来。

    无法购买的商品i,必定满足li,ri在某两个相邻点之间,也就是说,可以购买的商品,必然会跨过若干个点。

    然后还有一个性质:对于d,所有ri-li>=d的i都是可以购买的(显然啦)。

    好的那么让我们开工:我们把所有商品按ri-li的大小排序,对于ri-li>=d的直接加上;其他商品,由于ri-li<d,它们最多跨过一个点,则我们只需要枚举跨过某个点的商品个数总和就好,这个通过差分思想,树状数组就ok。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n,m;
    struct node{int l,r;
    }a[300010];
    bool cmp(node x,node y){return x.r-x.l<y.r-y.l;}
    
    int tree[100010];
    void add(int id,int x){for(;id<=m;id+=id&-id) tree[id]+=x;}
    int query(int id){int re=0;for(;id;id-=id&-id) re+=tree[id];return re;}
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%d%d",&a[i].l,&a[i].r);
        sort(a+1,a+n+1,cmp);
        for (int i=1,j=0;i<=m;i++)
        {
            int cnt=0;
            for (int t=i;t<=m;t+=i) cnt+=query(t);
            printf("%d
    ",cnt+n-j);
            while (j<n&&a[j+1].r-a[j+1].l<=i)
            {
                add(a[j+1].l,1);
                add(a[j+1].r+1,-1);
                j++;
            }
        }
    }
  • 相关阅读:
    AGC037F Counting of Subarrays
    AGC025F Addition and Andition
    CF506C Mr. Kitayuta vs. Bamboos
    AGC032D Rotation Sort
    ARC101F Robots and Exits
    AGC032E Modulo Pairing
    CF559E Gerald and Path
    CF685C Optimal Point
    聊聊Mysql索引和redis跳表
    什么是线程安全
  • 原文地址:https://www.cnblogs.com/coco-night/p/9513947.html
Copyright © 2011-2022 走看看