zoukankan      html  css  js  c++  java
  • ACdream 1157 (cdq分治)

    题目链接

    Segments

    Time Limit: 4000/2000MS (Java/Others)Memory Limit: 20000/10000KB (Java/Others)

    Problem Description

    由3钟类型操作:
    1)D L R(1 <= L <= R <= 1000000000) 增加一条线段[L,R]
    2)C i (1-base) 删除第i条增加的线段,保证每条插入线段最多插入一次,且这次删除操作一定合法
    3) Q L R(1 <= L <= R <= 1000000000) 查询目前存在的线段中有多少条线段完全包含[L,R]这个线段,线段X被线段Y完全包含即LY <= LX

    <= RX <= RY)
    给出N,接下来N行,每行是3种类型之一

    Input

    多组数据,每组数据N

    接下来N行,每行是三种操作之一(1 <= N  <= 10^5)

    Output

    对于每个Q操作,输出一行,答案

    Sample Input

    6
    D 1 100
    D 3 8
    D 4 10
    Q 3 8
    C 1
    Q 3 8

    Sample Output

    2
    1

    Hint

    注意,删除第i条增加的线段,不是说第i行,而是说第i次增加。

    比如

    D 1 10

    Q 1 10

    D 2 3

    D 3 4

    Q 5 6

    D 5 6

    C 2是删除D 2 3

    C 4是删除D 5 6

    第一次听说cdq分治,cdq是陈丹琦orz。。

     在我们平常使用的分治中,每一个子问题只解决它本身(可以说是封闭的)。

    而在cdq分治中,对于划分出来的两个子问题,前一个子问题用来解决后一个子问题而不是它本身。

    具体算法流程如下:

    1.将整个操作序列分为两个长度相等的部分(分)

    2.递归处理前一部分的子问题(治1)

    3.计算前一部分的子问题中的修改操作对后一部分子问题的影响(治2)

    4.递归处理后一部分子问题(治3)

    另外,能使用常量引用的地方尽量使用,可以提高效率。

    Accepted Code:

     

      1 /*************************************************************************
      2     > File Name: 1157.cpp
      3     > Author: Stomach_ache
      4     > Mail: sudaweitong@gmail.com
      5     > Created Time: 2014年08月10日 星期日 08时24分10秒
      6     > Propose: 
      7  ************************************************************************/
      8 
      9 #include <cmath>
     10 #include <string>
     11 #include <cstdio>
     12 #include <vector>
     13 #include <fstream>
     14 #include <cstring>
     15 #include <iostream>
     16 #include <algorithm>
     17 using namespace std;
     18 
     19 const int maxn = 100055;
     20 int c[maxn<<1], l[maxn], r[maxn], ans[maxn];
     21 struct node {
     22       int t, id, l, r;
     23     node() {}
     24     node(int a, int b, int c, int d) {
     25           t = a; id = b; l = c; r = d;
     26     }
     27 }a[maxn];
     28 vector<int> xs;
     29 int w;
     30 
     31 bool cmp1(const node &a, const node &b) {
     32       return a.id < b.id;
     33 }
     34 
     35 bool cmp2(const node &a, const node &b) {
     36       if (a.l != b.l) return a.l < b.l;
     37     return a.r > b.r;
     38 }
     39 
     40 int lowbit(int x) {
     41       return x & -x;
     42 }
     43 
     44 void add(int x, int v) {
     45       x = 2*maxn - x;
     46       while (x < maxn*2) {
     47           c[x] += v;
     48         x += lowbit(x);
     49     }
     50 }
     51 
     52 int sum(int x) {
     53       int res = 0;
     54     x = 2*maxn - x;
     55     while (x > 0) {
     56           res += c[x];
     57         x -= lowbit(x);
     58     }
     59     return res;
     60 }
     61 
     62 void solve(int l, int r) {
     63       if (l >= r) return ;
     64     int mid = (l + r) >> 1;
     65     solve(l, mid);
     66     sort(a+l, a+r+1, cmp2);
     67     for (int i = l; i <= r; i++) {
     68           if (a[i].id <= mid) {
     69               if (a[i].t == 1) add(a[i].r, 1);
     70             else if (a[i].t == -1) add(a[i].r, -1);
     71         } else {
     72               if (a[i].t == 0) ans[a[i].id] += sum(a[i].r);
     73         }
     74     }
     75     for (int i = l; i <= r; i++) if (a[i].id <= mid) {
     76           if (a[i].t == 1) add(a[i].r, -1);
     77         if (a[i].t == -1) add(a[i].r, 1);
     78     }
     79     sort(a+l, a+r+1, cmp1);
     80     solve(mid+1, r);
     81 }
     82 
     83 int main(void) {
     84       int n;
     85       while (~scanf("%d", &n)) {
     86           int cnt = 1;
     87         xs.clear();
     88           for (int i = 1; i <= n; i++) {
     89               char s[10];
     90               scanf("%s", s);
     91             if (s[0] == 'D') {
     92                   int x, y;
     93                 scanf("%d %d", &x, &y);
     94                 xs.push_back(x);
     95                 xs.push_back(y);
     96                 l[cnt] = x;
     97                 r[cnt++] = y;
     98                 a[i] = node(1, i, x, y);
     99             } else if (s[0] == 'Q') {
    100                   int x, y;
    101                 scanf("%d %d", &x, &y);
    102                 xs.push_back(x);
    103                 xs.push_back(y);
    104                 a[i] = node(0, i, x, y);    
    105             } else {
    106                   int id;
    107                 scanf("%d", &id);
    108                 a[i] = node(-1, i, l[id], r[id]);
    109             }
    110         }
    111         sort(xs.begin(), xs.end());
    112         xs.erase(unique(xs.begin(), xs.end()), xs.end());
    113         w = xs.size();
    114         for (int i = 1; i <= n; i++) {
    115               a[i].l = lower_bound(xs.begin(), xs.end(), a[i].l)-xs.begin()+1;
    116               a[i].r = lower_bound(xs.begin(), xs.end(), a[i].r)-xs.begin()+1;
    117             //printf("%d %d
    ", a[i].l, a[i].r);
    118         }
    119         //memset(c, 0, sizeof(c));
    120         memset(ans, 0, sizeof(ans));
    121         solve(1, n);
    122         for (int i = 1; i <= n; i++) if (!a[i].t) printf("%d
    ", ans[i]);
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    redis--pipelining管道
    插入排序
    选择排序
    冒泡排序
    网页表格导入导出Excel
    easyUI的datagrid表格的使用
    软件工程实践总结(个人)
    Beta答辩总结
    Beta冲刺7
    Beta冲刺6
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3902517.html
Copyright © 2011-2022 走看看