zoukankan      html  css  js  c++  java
  • HDU5140---Hun Gui Wei Company (主席树)

    主席树太强大了,,如果仅仅用来求第k大就太屈才了。。貌似和HDU4605差不多,那个是在图上根据点的顺序建立主席树,这个是根据年龄大小 或者等级高低建立主席树。

    题意 大致就是一个二维区间的求和,但是数量级很大,显然不能直接求。

    一个想法是可以二维线段树,但是这样显然会MLE。

    另外一个还是主席树,以age或者level顺序建立主席树,我是以age建立的。

    然后对应的查找就是 查找 tree[LA-1] 、tree[HA]之间的线段树 等级在LL HL之间的salary的和。

    题目强制要求在线算,只需要把 k更新后询问的LL HL LA HA 离散化就可以了。

      1 #include <cstdio>
      2 #include <string>
      3 #include <vector>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <algorithm>
      7 using namespace std;
      8 typedef unsigned long long ull;
      9 typedef long long ll;
     10 const int inf = 0x3f3f3f3f;
     11 const double eps = 1e-8;
     12 const int maxn = 1e5+10;
     13 int tot,tree[maxn],c[maxn*20],lson[maxn*20],rson[maxn*20];
     14 ll sum[maxn*20];
     15 int build (int l, int r)
     16 {
     17     int root = tot++;
     18     c[root] = sum[root] = 0;
     19     if (l != r)
     20     {
     21         int mid = (l + r) >> 1;
     22         lson[root] = build(l,mid);
     23         rson[root] = build(mid+1,r);
     24     }
     25     return root;
     26 }
     27 int MAX;
     28 int update (int root,int pos,int val,ll sa)
     29 {
     30     int newroot = tot++;
     31     int tmp = newroot;
     32     int l = 1, r = MAX;
     33     c[newroot] = c[root] + val;
     34     sum[newroot] = sum[root] + sa;
     35     while (l < r)
     36     {
     37         int mid = (l + r) >> 1;
     38         if (pos <= mid)
     39         {
     40             r = mid;
     41             rson[newroot] = rson[root];
     42             root = lson[root];
     43             lson[newroot] = tot++;
     44             newroot = lson[newroot];
     45         }
     46         else
     47         {
     48             l = mid + 1;
     49             lson[newroot] = lson[root];
     50             root = rson[root];
     51             rson[newroot] = tot++;
     52             newroot = rson[newroot];
     53         }
     54         c[newroot] = c[root] + val;
     55         sum[newroot] = sum[root] + sa;
     56     }
     57     return tmp;
     58 }
     59 ll query(int root1,int root2,int l,int r,int ua,int ub)
     60 {
     61     if (ua > ub)
     62         return 0;
     63     if (ua <= l && ub >= r)
     64     {
     65         return sum[root2] - sum[root1];
     66     }
     67     int mid = (l + r) >> 1;
     68     ll t1 = 0, t2 = 0;
     69     if (ua <= mid)
     70         t1 = query(lson[root1],lson[root2],l,mid,ua,ub);
     71     if (ub > mid)
     72         t2 = query(rson[root1],rson[root2],mid+1,r,ua,ub);
     73     return t1 + t2;
     74 }
     75 int lev[maxn],idx1,idx2,age[maxn];
     76 
     77 struct worker
     78 {
     79     int s,l,a;
     80     bool operator < (const worker &rhs)const
     81     {
     82         return a < rhs.a;
     83     }
     84 } per[maxn];
     85 int main(void)
     86 {
     87 #ifndef ONLINE_JUDGE
     88     freopen("in.txt","r",stdin);
     89  #endif
     90     int n;
     91     while (~scanf ("%d",&n))
     92     {
     93         tot = 0;
     94         memset(sum,0,sizeof(sum));
     95         MAX = n;
     96         int max_age = 0,min_age = inf;
     97         for (int i = 1; i <= n; i++)
     98         {
     99             scanf ("%d%d%d",&per[i].s, &per[i].l, &per[i].a);
    100             age[i-1] = per[i].a;
    101             lev[i-1] = per[i].l;
    102             max_age = max(max_age,age[i-1]);
    103             min_age = min(min_age,age[i-1]);
    104         }
    105         sort(per+1, per+1+n);
    106         sort(age, age+n);
    107         sort(lev, lev+n);
    108         idx1 = n;
    109         idx2 = unique(lev,lev+n) - lev;
    110 
    111         tree[0] = build(1,n);
    112         for (int i = 1; i <= n; i++)
    113         {
    114             int tmp = lower_bound(lev,lev+idx2,per[i].l) - lev + 1;
    115             tree[i] = update(tree[i-1], tmp, 1, (ll)per[i].s);
    116         }
    117         int Q;
    118         ll k = 0;
    119         scanf ("%d",&Q);
    120         for (int i = 0; i < Q; i++)
    121         {
    122             ll LL,HL,LA,HA;
    123             scanf ("%I64d%I64d%I64d%I64d",&LL,&HL,&LA,&HA);
    124             LL += k, HL -= k;
    125             LA += k, HA -= k;
    126             if (LL > HL)
    127                 swap(LL, HL);
    128             if (LA > HA)
    129                 swap(LA, HA);
    130             LA = max(LA, (ll)0);
    131             HA = min(HA, (ll)1000000000);
    132             int idx_la = lower_bound(age,age+idx1,LA) - age + 1;
    133             int idx_ha = lower_bound(age,age+idx1,HA) - age + 1;
    134             if (age[idx_ha-1] == HA)
    135             {
    136                 while (age[idx_ha-1] == HA && idx_ha <= n)
    137                     idx_ha ++;
    138                 idx_ha--;
    139             }
    140             else
    141                 idx_ha--;
    142             LL = max(LL,(ll)0);
    143             HL = min(HL,(ll)1000000000);
    144             int i1 = lower_bound(lev,lev+idx2,LL) - lev + 1;
    145             int i2 = lower_bound(lev,lev+idx2,HL) - lev + 1;
    146             if (lev[i2-1] > HL)
    147                 i2--;
    148             k = query(tree[idx_la-1],tree[idx_ha],1,MAX,i1,i2);
    149             printf("%I64d
    ",k);
    150         }
    151     }
    152     return 0;
    153 }
    154 
    155 /*
    156 5
    157 1 2 2
    158 2 3 3
    159 3 4 4
    160 4 5 6
    161 6 5 8
    162 1
    163 2 3 2 8
    164 
    165 3
    166 5 6 4
    167 2 8 6
    168 4 8 6
    169 1
    170 6 8 4 6
    171 */
  • 相关阅读:
    web网页测试用例(非常实用)
    怎么做web接口测试
    我的周记13——”离开,是为了更好的回来"
    Lambda 表达式常用函数
    IEnumberable<T>接口
    Linq的学习
    未能加载文件或程序集“Newtonsoft.Json”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。
    拉姆达表达式的笔记
    注册今日头条
    爬取百思不得姐的段子
  • 原文地址:https://www.cnblogs.com/oneshot/p/4151843.html
Copyright © 2011-2022 走看看