zoukankan      html  css  js  c++  java
  • HDU 3333 Turing Tree

    原题链接为:HDU-3333

    题意是给一组数,给定m个区间查询,询问这个区间中不同的数的和(即所有重复出现的数只当作一个数)。

    首先这是一道数据结构的题。这道题的关键在于离线化处理后用树状数组处理。把所有询问离线之后,按照右边界排序,然后依次处理。

    处理的办法是依次向右扫描,假设现在扫描到i处,则首先查询i处数值d[i]之前是否出现过。若没出现过,则在树状数组中,在i处加上d[i];若出现过,假设之前出现处为j,则在树状数组中j处减去d[j],同时在i处加上d[i]。可以发现,因为i之前的所有查询均已处理过, 所以这样的处理并不会影响结果。

    简单的说,思路就是用树状数组从左向右存储数,把所有数尽可能的往右存。

    为了记录d[i]是否出现过,需要离线化处理。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 
     5 struct Query
     6 {
     7     LL l,r;
     8     bool operator < (const Query x)
     9     {
    10         if(r==x.r) return l<x.l;
    11         return r<x.r;
    12     }
    13 };
    14 LL d[30010];
    15 Query q[100010];
    16 LL qq[100010];
    17 #define MAXN 100010
    18 LL n,m,tree[MAXN];
    19 LL lowbit(LL x)
    20 {
    21     return x&(-x);
    22 }
    23 void add(LL k,LL num)
    24 {
    25     while(k<=n)
    26     {
    27         tree[k]+=num;
    28         k+=lowbit(k);
    29     }
    30 }
    31 LL sum(LL k)
    32 {
    33     LL ans=0;
    34     while(k)
    35     {
    36         ans+=tree[k];
    37         k-=lowbit(k);
    38     }
    39     return ans;
    40 }
    41 map<LL,LL> dict;
    42 LL vis[30010];
    43 LL ans[100010];
    44 bool cmp(LL a,LL b)
    45 {
    46     return q[a]<q[b];
    47 }
    48 int main()
    49 {
    50 #ifdef LOCAL
    51     freopen("in.txt","r",stdin);
    52 #endif
    53     LL t;
    54     scanf("%lld",&t);
    55     while(t--)
    56     {
    57         LL dictnum=0;
    58         dict.clear();
    59         scanf("%lld",&n);
    60         for(LL i=1;i<=n;i++)
    61         {
    62             scanf("%lld",&d[i]);
    63             if(!dict.count(d[i])) dict[d[i]]=++dictnum;
    64         }
    65         scanf("%lld",&m);
    66         for(LL i=1;i<=m;i++) scanf("%lld%lld",&q[i].l,&q[i].r);
    67         for(LL i=1;i<=m;i++) qq[i]=i;
    68         sort(qq+1,qq+m+1,cmp);
    69         q[0].r=q[0].l=0;
    70         qq[0]=0;
    71         memset(tree,0,sizeof(tree));
    72         memset(vis,0,sizeof(vis));
    73         for(LL i=1;i<=m;i++)
    74         {
    75             for(LL j=q[qq[i-1]].r+1;j<=q[qq[i]].r;j++)
    76             {
    77                 if(vis[dict[d[j]]]) add(vis[dict[d[j]]],-d[j]);
    78                 add(j,d[j]);
    79                 vis[dict[d[j]]]=j;
    80             }
    81             ans[qq[i]]=sum(q[qq[i]].r)-sum(q[qq[i]].l-1);
    82         }
    83         for(LL i=1;i<=m;i++) printf("%lld
    ",ans[i]);
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    Bluetooth architecture (HCI/L2CAP)
    堆栈
    Inside the C++ Object Model 深度探索对象模型 57
    Android音乐播放器
    (一)开发板系统安装
    html5的canvas写一个简单的画板程序
    C++ 获取日历时间
    Incremental Differential vs. Incremental Cumulative Backups
    BCB安装控件出现Unresolved external '__fastcall Outline::TCustomOutline
    Windows 环境下配置 Oracle 11gR2 Data Guard 手记
  • 原文地址:https://www.cnblogs.com/zarth/p/6364724.html
Copyright © 2011-2022 走看看