zoukankan      html  css  js  c++  java
  • HDU 3874 Necklace(树状数组+离线处理)

     

    题目大意

     

    有一串长度为 n(1≤n50000) 的项链,项链上每块石头都有一个价值,在计算项链上一段连续石头的价值和的时候,相同价值的只计算一次

    现在给你 m(1≤m≤200000) 个询问,每个询问要查询一段连续石头 [L, R] (1≤L≤R≤n)的价值和

     

    做法分析

     

    先把所有的查询保存,然后按照查询区间的右端点由小到大排序,然后离线处理:


    对于一个具体的石头的价值 val,由于我们是按照查询的右端点从小到大排序的,我们当然就希望这个价值出现的位置越靠后(编号越大)越好了,这样就能够保证我们在查询一段区间的和的时候不会算漏了,也就是说,只保留每个价值最靠后的那一块石头,不断的向后加石头更新就行了,具体的说就是这样做的:

            每加一块石头(编号是 id),看这个石头的 val 是否出现过,如果没有出现过,直接加进去就行,然后 last[val]=id

            如果出现过,要先把 last[val] 这个位置的值减去 val,然后在更新,接着给 last[val] 更新:last[val]=id

            如果当前的这块石头是某个查询 [L, R] 的右端点,那么,这个时候直接查询 [L, R] 这段区间的和就行

    当然,我们也可以把按照左端点从大到小排序,不过这样的话,我们就得倒着扫石头了

     

    参考代码

    HDU 3874
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 typedef __int64 LL;
     9 const int N=50006;
    10 
    11 struct Node
    12 {
    13     int L, R, id;
    14     inline void init(int a, int b, int c)
    15     {
    16         L=a, R=b, id=c;
    17     }
    18 
    19     inline bool operator <(const Node &temp) const
    20     {
    21         if(R==temp.R) return L<temp.L;
    22         else return R<temp.R;
    23     }
    24 } op[200006];
    25 int t, n, m, last[1000006], data[N];
    26 LL BIT[N];
    27 
    28 void update(int pos, int val)
    29 {
    30     for(; pos<N; pos+=pos&(-pos)) BIT[pos]+=val;
    31 }
    32 
    33 LL query(int pos)
    34 {
    35     LL sum=0;
    36     for(; pos>0; pos-=pos&(-pos)) sum+=BIT[pos];
    37     return sum;
    38 }
    39 
    40 LL ans[200006];
    41 
    42 int main()
    43 {
    44     scanf("%d", &t);
    45     for(int ca=1; ca<=t; ca++)
    46     {
    47         scanf("%d", &n);
    48         for(int i=1; i<=n; i++)
    49         {
    50             scanf("%d", &data[i]);
    51             last[data[i]]=-1;
    52         }
    53         scanf("%d", &m);
    54         for(int i=0, a, b; i<m; i++)
    55         {
    56             scanf("%d%d", &a, &b);
    57             if(a>b) swap(a, b);
    58             op[i].init(a, b, i);
    59         }
    60         sort(op, op+m);
    61         memset(BIT, 0, sizeof BIT);
    62         for(int i=0, u=1; i<m; i++)
    63         {
    64             for(; u<=op[i].R; u++)
    65             {
    66                 if(last[data[u]]!=-1) update(last[data[u]], -data[u]);
    67                 last[data[u]]=u;
    68                 update(u, data[u]);
    69             }
    70             ans[op[i].id]=query(op[i].R)-query(op[i].L-1);
    71         }
    72         for(int i=0; i<m; i++) printf("%I64d\n", ans[i]);
    73     }
    74     return 0;
    75 }

    题目链接 & AC通道

    HDU 3874 Necklace

  • 相关阅读:
    mysql 查看表注解
    oracle 相关
    sql version control
    ccna
    msql 清库
    mybatisplus,application.properties 配置数据库密码加密
    驱动开发print无法输出问题
    bochs帮助
    以虚御虚用虚拟机调试vt程式
    ssm整合
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/3042291.html
Copyright © 2011-2022 走看看