HDU 3874 Necklace(离线算法+树状数组)

题目链接

离线算法,以前做过一个,非常神奇。

先把所有的区间,按Y排序,再按X排,然后算每一个区间,如果遇到了相同的就把前一个点更新一下-num[le],当前点插入。如果相同直接插入。再区间求和,记录结果。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 #define N 200001
 7 #define LL __int64
 8 struct node
 9 {
10     int x,y,id;
11 }que[N];
12 int hash[1000001];
13 int n;
14 LL p[50001];
15 int num[50001];
16 LL output[N];
17 void CL()
18 {
19     memset(p,0,sizeof(p));
20     memset(hash,0,sizeof(hash));
21 }
22 int cmp(node a,node b)
23 {
24     if(a.y == b.y)
25     return a.x < b.x;
26     else
27     return a.y < b.y;
28 }
29 int lowbit(int t)
30 {
31     return t&(-t);
32 }
33 void insert(int t,int d)
34 {
35     while(t <= n)
36     {
37         p[t] += d;
38         t += lowbit(t);
39     }
40 }
41 LL getsum(int t)
42 {
43     LL sum = 0;
44     if(t == 0) return 0;
45     while(t > 0)
46     {
47         sum += p[t];
48         t -= lowbit(t);
49     }
50     return sum;
51 }
52 int main()
53 {
54     int i,cas,m,le;
55     scanf("%d",&cas);
56     while(cas--)
57     {
58         CL();
59         scanf("%d",&n);
60         for(i = 1;i <= n;i ++)
61         scanf("%d",&num[i]);
62         scanf("%d",&m);
63         for(i = 1;i <= m;i ++)
64         {
65             scanf("%d%d",&que[i].x,&que[i].y);
66             que[i].id = i;
67         }
68         sort(que+1,que+m+1,cmp);
69         le = 1;
70         for(i = 1;i <= m;i ++)
71         {
72             while(le <= que[i].y)
73             {
74                 if(hash[num[le]])
75                 {
76                     insert(hash[num[le]],-num[le]);
77                 }
78                 hash[num[le]] = le;
79                 insert(le,num[le]);
80                 le ++;
81             }
82             output[que[i].id] = getsum(que[i].y) - getsum(que[i].x-1);
83         }
84         for(i = 1;i <= m;i ++)
85         printf("%I64d\n",output[i]);
86     }
87     return 0;
88 }

 

 

posted @ 2013-05-30 20:26  Naix_x  阅读(204)  评论(0编辑  收藏  举报