zoukankan      html  css  js  c++  java
  • 【做题】arc068_e-Snuke Line——利用特殊性质分讨

    显然,对于所有跨度暴力扫一遍的复杂度本身只有(O(n log n))
    容易想到在每一个到达的位置加上覆盖这个位置的区间数。剩下的问题就在于如何处理覆盖了多个位置的区间。
    记录已访问或去重都是难以实现的。但注意到一个性质:

    所有长度不小于跨度的区间一定都能被访问到,所有长度小于跨度的区间至多访问一次。

    于是我们枚举跨度,维护长度不小于当前跨度的区间数,把长度小于当前跨度的区间加入到一个支持区间加和单点查询的数据结构里就可以了。
    时间复杂度(O(n log ^2 n))

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 300010, M = 100010;
    #define lowbit(x) ((x) & (-(x)))
    int v[M],n,m,s,ans,p=1;
    struct data {
      int l,r;
      bool operator < (const data& x) const {
        return r - l < x.r - x.l;
      }
    } dat[N];
    void add(int p,int val) {
      for (; p <= s ; p += lowbit(p))
        v[p] += val;
    }
    int query(int p) {
      int res = 0;
      for (; p ; p -= lowbit(p))
        res += v[p];
      return res;
    }
    int main() {
      scanf("%d%d",&n,&m);
      for (int i = 1 ; i <= n ; ++ i)
        scanf("%d%d",&dat[i].l,&dat[i].r);
      sort(dat+1,dat+n+1);
      s = m+1;
      for (int i = 1 ; i <= m ; ++ i) {
        while (dat[p].r - dat[p].l + 1 < i && p <= n) {
          add(dat[p].l+1,1);
          add(dat[p].r+2,-1);
          p ++;
        }
        ans = n - p + 1;
        for (int j = 0 ; j <= m ; j += i)
          ans += query(j+1);
        printf("%d
    ",ans);
      }
      return 0;
    }
    

    小结:利用题目特殊性质分类讨论可以有效简化题目。
  • 相关阅读:
    第一次Java测试及感触
    第七周学习
    第六周学习
    第5周学习
    第四周学习
    第三周学习
    浅略学习
    读完《大道至简》后的小感悟
    初识JAVA
    Java课后作业之石家庄地铁系统PSP表格20190403
  • 原文地址:https://www.cnblogs.com/cly-none/p/8997726.html
Copyright © 2011-2022 走看看