zoukankan      html  css  js  c++  java
  • CF369E Valera and Queries

    嘟嘟嘟


    这题刚开始以为是一个简单题,后来越想越不对劲,然后就卡住了。
    瞅了一眼网上的题解(真的只瞅了一眼),几个大字令人为之一振:正难则反!
    没错,把点看成区间,比如2, 5, 6, 9就是[1, 1], [3, 4], [7, 8], [10, INF]。然后只要看给定的哪些线段完全包含在这些区间里了。


    预处理出这些区间后,离线下来,按左端点从大到小,右端点从从小到大排序。遇到一个线段就加进树状数组里,遇到一个区间就查一下R的前缀和。因为我们是左端点从大到小扫的,所以一定保证加进树状数组的线段的左端点大于等于当前查询区间的左端点。所以只用考虑右端点即可。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 3e5 + 5;
    const int maxN = 1e6 + 5;
    inline ll read()
    {
      ll ans = 0;
      char ch = getchar(), last = ' ';
      while(!isdigit(ch)) last = ch, ch = getchar();
      while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
      if(last == '-') ans = -ans;
      return ans;
    }
    inline void write(ll x)
    {
      if(x < 0) x = -x, putchar('-');
      if(x >= 10) write(x / 10);
      putchar(x % 10 + '0');
    }
    
    int n, m, Max = 0;
    struct Seg
    {
      int L, R, id;
      In bool operator < (const Seg& oth)const
      {
        if(L ^ oth.L) return L > oth.L;
        if(R ^ oth.R) return R < oth.R;
        return id < oth.id;
      }
    }t[maxn << 2];
    
    int cnt = 0, tp[maxn], ans[maxn];
    
    int c[maxN];
    In int lowbit(int x) {return x & -x;}
    In void add(int pos)
    {
      for(; pos < maxN; pos += lowbit(pos)) ++c[pos];
    }
    In int query(int pos)
    {
      int ret = 0;
      for(; pos; pos -= lowbit(pos)) ret += c[pos];
      return ret;
    }
    
    int main()
    {
      n = read(); m = read(); cnt = n;
      for(int i = 1; i <= n; ++i) t[i].L = read(), t[i].R = read(), t[i].id = 0;
      for(int i = 1; i <= m; ++i)
        {
          int tot = read();
          for(int j = 1; j <= tot; ++j) tp[j] = read();
          for(int j = 1; j <= tot; ++j)
    	if(tp[j] > 1 && tp[j - 1] < tp[j] - 1) t[++cnt] = (Seg){tp[j - 1] + 1, tp[j] - 1, i};
          t[++cnt] = (Seg){tp[tot] + 1, maxN - 5, i};
        }
      sort(t + 1, t + cnt + 1);
      for(int i = 1; i <= cnt; ++i)
        if(t[i].id) ans[t[i].id] += query(t[i].R);
        else add(t[i].R);
      for(int i = 1; i <= m; ++i) write(n - ans[i]), enter;
      return 0;
    }
    
  • 相关阅读:
    SQL Server数据库文件与文件组总结
    SQL Server使用sp_rename重命名约束注意事项
    LogWriter: Operating system error 21(error not found) encountered
    SQL Server的Linked Server支持使用SEQUENCE吗?
    SQL Server使用sp_spaceused查看表记录存在不准确的情况
    SQL Server死锁中的会话隔离级别为序列化(Serializable)实验测试
    SQL Server统计信息偏差影响表联结方式案例浅析
    SQL Server关于predicate、density、selectivity、cardinality名词浅析
    Oracle dblink的连接模式的关系测试总结
    MySQL系统变量sql_safe_updates总结
  • 原文地址:https://www.cnblogs.com/mrclr/p/10387855.html
Copyright © 2011-2022 走看看