zoukankan      html  css  js  c++  java
  • Codeforces Round #216 (Div. 2) E. Valera and Queries 树状数组 离线处理

    题意:n个线段[Li, Ri], m次询问, 每次询问由cnt个点组成,输出包含cnt个点中任意一个点的线段的总数。

    由于是无修改的,所以我们首先应该往离线上想, 不过我是没想出来。

    首先反着做,先求不包含这个cnt个点的线段的总数, 那么不包含这些点的线段必然在cnt个点之间(这里需要再加两个点一个是0, 一个是MAX),

    我们可以把所有线段按R分类, 然后按右端点遍历,对于当前的线段可以在Li 处+1, 然后对于每一次询问中两个点(x, y)之间线段的个数,

    只需要查询 左端点大于等于x的个数就好了,这里因为是按右端点从小到大遍历的,所以不用考虑用端点了。

    发现, 大多数的离线处理都是先把其中的一维从小到大排序, 然后处理另一维。 这样相当于降维。

     1 #include <bits/stdc++.h>
     2 
     3 const int maxn = 1e6 + 10;
     4 typedef std::pair <int, int> pii;
     5 std::vector <int> seg[maxn], q[maxn];
     6 std::vector <pii> rq[maxn];
     7 namespace FenwickTree{
     8     int arr[maxn];
     9     void inc(int x, int d){
    10         while (x < maxn){
    11             arr[x] += d;
    12             x += x & -x;
    13         }
    14     }
    15     int query(int x){
    16         int res = 0;
    17         while (x > 0){
    18             res += arr[x];
    19             x -= x & -x;
    20         }
    21         return res;
    22     }
    23     int query(int ua, int ub){
    24         return query(ub) - query(ua-1);
    25     }
    26 }
    27 int ans[maxn];
    28 void init(){
    29     memset(ans, 0, sizeof (ans));
    30     for (int i = 0; i < maxn; i++){
    31         seg[i].clear();
    32         q[i].clear();
    33         rq[i].clear();
    34     }
    35 }
    36 int main()
    37 {
    38     #ifndef ONLINE_JUDGE
    39         freopen("in.txt", "r", stdin);
    40     #endif // ONLINE_JUDGE
    41     int n, m;
    42     while (~ scanf ("%d%d", &n, &m)){
    43         init();
    44         for (int i = 0; i < n; i++){
    45             int ua, ub;
    46             scanf("%d%d", &ua, &ub);
    47             ua++, ub++;
    48             seg[ub].push_back(ua);
    49         }
    50         for (int i = 0; i < m; i++){
    51             int cnt, p;
    52             scanf ("%d", &cnt);
    53             q[i].push_back(1);
    54             while (cnt--){
    55                 scanf ("%d", &p);
    56                 p++;
    57                 q[i].push_back(p);
    58             }
    59             q[i].push_back(maxn-1);
    60             for (int j = 0; j < q[i].size()-1; j++){
    61                 int ua = q[i][j]+1;
    62                 int ub = q[i][j+1]-1;
    63                 rq[ub].push_back(std::make_pair(ua, i));
    64             }
    65         }
    66         for (int i = 1; i < maxn; i++){
    67             for (int j = 0; j < seg[i].size(); j++){
    68                 int tmp = seg[i][j];
    69                 FenwickTree::inc(seg[i][j], 1);
    70             }
    71             for (int j = 0; j < rq[i].size(); j++){
    72                 int idx = rq[i][j].second;
    73                 int tmp = rq[i][j].first;
    74                 ans[idx] += FenwickTree::query(rq[i][j].first, i);
    75             }
    76         }
    77         for (int i = 0; i < m; i++){
    78             printf("%d
    ", n - ans[i]);
    79         }
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    VCL消息处理机制
    效率由心生,快速提高工作效率秘诀
    我的插件架构
    Windows消息机制要点(转)
    SQLite区分大小写查询
    请教: 事件和消息的联系?
    DataAdapter数据集DataSet和数据库的同步(3):使用CommandBuilder来更新数据集
    TCP编程(4): 发送电子邮件 MailMessage, SmtpClient, NetworkCredential
    强类型的数据集,在处理以直接附加方式的SQLServer的MDF文件时无法更新数据原因分析
    javascript调试测试,利用vs2008:智能对象类型感知,方法及属性提示;立即窗口调试等
  • 原文地址:https://www.cnblogs.com/oneshot/p/4860888.html
Copyright © 2011-2022 走看看