码迷,mamicode.com
首页 > 编程语言 > 详细

Hdu 5372 Segment Game (树状数组)

时间:2015-08-12 18:59:36      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

  Hdu 5372 Segment Game

题目描述:

  有一段区间,对这段区间有两种操作。1:插入操作,第i次插入长度为i的线段,并询问被当前线段完全覆盖的线段数目。

                   2:删除操作,删除第b次插入的线段。

解题思路:

  对于当前新插入线段,只需要统计已插入线段中右端点小于该线段右端点的数目,以及左端点小于该线段做端点的数目,两者相减即可。还有就是离散化问题,sort+unique+map真的是离散化利器(啧啧啧~)。

 1 #include <map>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 200005;
 9 typedef long long LL;
10 struct opera
11 {
12     int a, l, r;
13 }p[maxn];
14 int cl[maxn], cr[maxn], al[maxn], ar[maxn], L[maxn];
15 
16 int lowbit (int x)
17 {
18     return x & (-x);
19 }
20 
21 int sum (int x, int a[])
22 {
23     int Sum = 0;
24     while (x > 0)
25     {
26         Sum += a[x];
27         x -= lowbit(x);
28     }
29     return Sum;
30 }
31 
32 void change (int i, int x, int a[], int n)
33 {
34     while (i <= n)
35     {
36         a[i] += x;
37         i += lowbit(i);
38     }
39 }
40 
41 int main ()
42 {
43     int n, m, cnt, t, cas = 0;
44     while (scanf ("%d", &t) != EOF)
45     {
46         memset (cl, 0, sizeof(cl));
47         memset (cr, 0, sizeof(cr));
48         n = m = cnt = 0;
49 
50         for (int i=0; i<t; i++)
51         {
52             scanf ("%d %d", &p[i].a, &p[i].l);
53             if (p[i].a == 0)
54             {
55                 cnt ++;
56                 p[i].r = p[i].l + cnt;
57                 al[n++] = p[i].l;
58                 ar[m++] = p[i].r;
59                 L[cnt] = p[i].l;
60             }
61         }
62 
63         sort (al, al+n);
64         n = unique (al, al+n) - al;
65         sort (ar, ar+m);
66         m = unique (ar, ar+m) - ar;
67         map <int, int> ml, mr;
68         
69         for (int i=0; i<n; i++)
70             ml[al[i]] = i + 1;
71         for (int i=0; i<m; i++)
72             mr[ar[i]] = i + 1;
73 
74         cnt = 0;
75         printf ("Case #%d:\n", ++cas);
76         for (int i=0; i<t; i++)
77         {
78             if (p[i].a)
79             {
80 
81                 int left = ml[L[p[i].l]];
82                 int right = mr[L[p[i].l]+p[i].l];
83                 change (left, -1, cl, n);
84                 change (right, -1, cr, m);
85             }
86             else
87             {
88                 int ansl = sum (ml[p[i].l]-1, cl);
89                 int ansr = sum (mr[p[i].r], cr);
90                 printf ("%d\n", ansr - ansl);
91                 change (ml[p[i].l], 1, cl, n);
92                 change (mr[p[i].r], 1, cr, m);
93             }
94         }
95     }
96     return 0;
97 }

好久没有写过树状数组了,基本忘光光>_<.....,今天算是从新温习了一下(感觉这个代码好渣,改天再改一下)

Hdu 5372 Segment Game (树状数组)

标签:

原文地址:http://www.cnblogs.com/alihenaixiao/p/4724973.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!