zoukankan      html  css  js  c++  java
  • HDU3874 /HDU3333 树状数组 区间求不重复数和

    Necklace

    Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 4604    Accepted Submission(s): 1581


    Problem Description
    Mery has a beautiful necklace. The necklace is made up of N magic balls. Each ball has a beautiful value. The balls with the same beautiful value look the same, so if two or more balls have the same beautiful value, we just count it once. We define the beautiful value of some interval [x,y] as F(x,y). F(x,y) is calculated as the sum of the beautiful value from the xth ball to the yth ball and the same value is ONLY COUNTED ONCE. For example, if the necklace is 1 1 1 2 3 1, we have F(1,3)=1, F(2,4)=3, F(2,6)=6.

    Now Mery thinks the necklace is too long. She plans to take some continuous part of the necklace to build a new one. She wants to know each of the beautiful value of M continuous parts of the necklace. She will give you M intervals [L,R] (1<=L<=R<=N) and you must tell her F(L,R) of them.
     
    Input
    The first line is T(T<=10), representing the number of test cases.
      For each case, the first line is a number N,1 <=N <=50000, indicating the number of the magic balls. The second line contains N non-negative integer numbers not greater 1000000, representing the beautiful value of the N balls. The third line has a number M, 1 <=M <=200000, meaning the nunber of the queries. Each of the next M lines contains L and R, the query.
     
    Output
    For each query, output a line contains an integer number, representing the result of the query.
     
    Sample Input
    2 6 1 2 3 4 3 5 3 1 2 3 5 2 6 6 1 1 1 2 3 5 3 1 1 2 4 3 5
     
    Sample Output
    3 7 14 1 3 6
     
    Source
    题意:
    给一串数,若干询问,每次询问一个区间内不重复数字之和。
    代码:
     1 /*
     2 把询问的几个区间先存起来,将其按照区间右端点从小到大排序,这样当去掉某一区间内的重复值时就不会
     3 影响其他区间,因为其他区间的右端点要么比他小,要么比他大,比他小的不会受影响(树状数组向上更新)
     4 ,比他大的恰好也要去重。去重时利用map。
     5 */
     6 #include<iostream>
     7 #include<cstdio>
     8 #include<map>
     9 #include<cstring>
    10 #include<algorithm>
    11 #include<cmath>
    12 const int MAXN=50005;
    13 const int MAXM=200005;//MAXM,MAXN改为30005,1000005就是HDU3333题题解
    14 long long A[MAXN];
    15 long long NE[MAXN];
    16 int t,n,m;
    17 struct Necklace
    18 {
    19     int R,L,id;//区间右端点,区间左端点,序号
    20 }neck[MAXM];
    21 bool cmp(Necklace a,Necklace b)
    22 {
    23     if(a.R==b.R)
    24     return a.L<b.L;
    25     else return a.R<b.R;
    26 }
    27 int lowbit(int x)
    28 {
    29     return x&(-x);
    30 }
    31 void add(int id,long long c)
    32 {
    33     while(id<=MAXN)
    34     {
    35         A[id]+=c;
    36         id+=lowbit(id);
    37     }
    38 }
    39 long long sum(int id)
    40 {
    41     long long s=0;
    42     while(id>0)
    43     {
    44         s+=A[id];
    45         id-=lowbit(id);
    46     }
    47     return s;
    48 }
    49 using namespace std;
    50 int main()
    51 {
    52     scanf("%d",&t);
    53     while(t--)
    54     {
    55         scanf("%d",&n);
    56         for(int i=1;i<=n;i++)
    57         scanf("%lld",&NE[i]);
    58         scanf("%d",&m);
    59         for(int i=0;i<m;i++)
    60         {
    61             scanf("%d%d",&neck[i].L,&neck[i].R);
    62           //  if(neck[i].L>neck[i].R)
    63           //  swap(neck[i].L,neck[i].R);
    64             neck[i].id=i;
    65         }
    66         sort(neck,neck+m,cmp);
    67         int p=1;
    68         map<int,int>mp;
    69         long long ans[MAXM];
    70         memset(A,0,sizeof(A));
    71         for(int i=0;i<m;i++)
    72         {
    73             while(p<=neck[i].R)//小于等于区间右端点的
    74             {
    75                 long long x=NE[p];
    76                 if(mp[x]!=0)//如果前面出现过此X值就减去旧的加上新的
    77                 add(mp[x],-x);
    78                 add(p,x);
    79                 mp[x]=p;
    80                 p++;
    81             }
    82             ans[neck[i].id]=sum(neck[i].R)-sum(neck[i].L-1);
    83         }
    84         for(int i=0;i<m;i++)
    85         printf("%lld
    ",ans[i]);
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    Visual GC(监控垃圾回收器)
    垃圾收集(GC)中如何确定哪些内存是"垃圾
    Java for循环和foreach循环的性能比较
    <mvc:annotation-driven />做了什么
    聊一聊分布式锁的设计
    String类对象的比较
    Java 中 Comparable 和 Comparator 比较
    系统对接API调用
    深入理解Java中的组合和继承
    面向对象设计七大原则
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/5914030.html
Copyright © 2011-2022 走看看