Qiuqiqiu  
不管道路多么崎岖坎坷,我永远不停下追逐梦想的脚步!

http://acm.hdu.edu.cn/showproblem.php?pid=3333

树状数组+离散化+离线算法

读入所有区间,按右端点排序,每加入一个数时,如果已经加过,就在该数原来位置减去它,在新位置加上它

View Code
 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 typedef __int64 LL;
 6 const int N=30010,Q=100010;
 7 int a[N],n,vis[N];
 8 int dz[N],nd;
 9 LL c[N];
10 struct extent
11 {
12     int u,v,p;
13     LL ans;
14 }e[Q];
15 bool cmp1(const extent &a,const extent &b)
16 {
17     return a.v<b.v;
18 }
19 bool cmp2(const extent &a,const extent &b)
20 {
21     return a.p<b.p;
22 }
23 int bfind(int x,int *a,int l,int r)
24 {
25     while(l<r)
26     {
27         int m=(l+r)/2;
28         if(x==a[m]) return m;
29         else if(x<a[m]) r=m;
30         else l=m+1;
31     }
32     return l;
33 }
34 int lowbit(int x)
35 {
36     return x&(-x);
37 }
38 void add(int x,int p,int maxn)
39 {
40     for(int i=p;i<=maxn;i+=lowbit(i))
41      c[i]+=x;
42 }
43 LL sum(int p)
44 {
45     LL s=0;
46     for(int i=p;i;i-=lowbit(i)) s+=c[i];
47     return s;
48 }
49 int main()
50 {
51     int T;
52     scanf("%d",&T);
53     while(T--)
54     {
55         int n;
56         scanf("%d",&n);
57         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
58         for(int i=0;i<n;i++) dz[i]=a[i+1];
59         sort(dz,dz+n);
60         nd=1;
61         for(int i=1;i<n;i++)
62             if(dz[i]!=dz[i-1]) dz[nd++]=dz[i];
63         int q;
64         scanf("%d",&q);
65         for(int i=0;i<q;i++)
66         {
67             scanf("%d%d",&e[i].u,&e[i].v);
68             e[i].p=i;
69         }
70         sort(e,e+q,cmp1);
71         memset(vis,0,sizeof(vis));
72         memset(c,0,sizeof(c));
73         int p=0;
74         for(int i=1;i<=n;i++)
75         {
76             add(a[i],i,n);
77             int x=bfind(a[i],dz,0,nd-1);
78             if(vis[x]) add(-a[i],vis[x],n);
79             vis[x]=i;
80             while(p<q && e[p].v==i)
81             {
82                 e[p].ans=sum(e[p].v)-sum(e[p].u-1);
83                 p++;
84             }
85         }
86         sort(e,e+q,cmp2);
87         for(int i=0;i<q;i++) printf("%I64d\n",e[i].ans);
88     }
89     return 0;
90 }

 

posted on 2012-04-10 15:25  Qiuqiqiu  阅读(195)  评论(0编辑  收藏  举报