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 }
  • 相关阅读:
    有return的情况下try catch finally的执行顺序
    for循环和foreach循环效率对比
    SpringBoot_数据访问-整合MyBatis-配置版MyBatis
    作品
    HTML——招生信息网(bootstrap、WOW动画、blueimp-gallery图片展示插件)
    HTML——信息技术基础精品课程
    HTML——校友会(bootstrap)
    毕设——社区志愿者信息管理系统
    HTML笔记——JS下载.json文件
    HTML笔记——bootstrap-select、table、tableExport、layer
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/5914030.html
Copyright © 2011-2022 走看看