zoukankan      html  css  js  c++  java
  • HDU 5919 Sequence II(主席树+区间不同数个数+区间第k小)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5919

    题意:
    给出一串序列,每次给出区间,求出该区间内不同数的个数k和第一个数出现的位置(将这些位置组成一个新的序列),输出这里面的第ceil(k/2)个数。

    思路:

    因为每个区间只需要统计第一个数出现的位置,那么从右往左来建树,如果该数没有出现,那么就将该位置+1,否则要将上一次出现的位置-1后再在该位置+1。

    统计不同数的个数很简单,就是线段树查询。

    查询出第k小的数也很简单,因为我们是从后往前建树的,那么t[l]这棵树里面的元素就是从l开始的数组,直接线段树查询第k个数即可。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<stack>
      7 #include<queue>
      8 #include<cmath>
      9 #include<map>
     10 #include<set>
     11 using namespace std;
     12 typedef long long ll;
     13 typedef pair<int,int> pll;
     14 const int INF = 0x3f3f3f3f;
     15 const int maxn = 2*1e5+5;
     16 
     17 int tot,n,m;
     18 int a[maxn],pre[maxn],rot[maxn];
     19 
     20 struct node
     21 {
     22     int l,r,num;
     23 }t[maxn*50];
     24 
     25 int build(int l, int r)
     26 {
     27     int root=++tot;
     28     t[root].num=0;
     29     if(l==r)  return root;
     30     int mid=(l+r)>>1;
     31     t[root].l=build(l,mid);
     32     t[root].r=build(mid+1,r);
     33     return root;
     34 }
     35 
     36 int update(int root, int pos, int d)
     37 {
     38     int now = ++tot;
     39     int tmp = now;
     40     t[tot].num = t[root].num + d;
     41     int l = 1, r = n;
     42     while(l<r)
     43     {
     44         int mid = (l+r)>>1;
     45         if(pos<=mid)
     46         {
     47             t[now].l = ++tot;
     48             t[now].r = t[root].r;
     49             root = t[root].l;
     50             now = tot;
     51             r = mid;
     52         }
     53         else
     54         {
     55             t[now].l = t[root].l;
     56             t[now].r = ++tot;
     57             root = t[root].r;
     58             now = tot;
     59             l = mid + 1;
     60         }
     61         t[now].num = t[root].num + d;
     62     }
     63     return tmp;
     64 }
     65 
     66 int query(int ql ,int qr, int l, int r, int root)
     67 {
     68     if(ql<=l && qr>=r)  return t[root].num;
     69     int mid = (l+r)>>1;
     70     int ans = 0;
     71     if(ql<=mid)  ans+=query(ql,qr,l,mid,t[root].l);
     72     if(qr>mid)   ans+=query(ql,qr,mid+1,r,t[root].r);
     73     return ans;
     74 }
     75 
     76 
     77 int calc(int l,int r,int k,int root)
     78 {
     79     if(l==r)  return l;
     80     int mid = (l+r)>>1;
     81     if(t[t[root].l].num>=k)  return calc(l,mid,k,t[root].l);
     82     else return calc(mid+1,r,k-t[t[root].l].num,t[root].r);
     83 }
     84 
     85 int main()
     86 {
     87     //freopen("in.txt","r",stdin);
     88     int T;
     89     int kase = 0;
     90     scanf("%d",&T);
     91     while(T--)
     92     {
     93         tot=0;
     94         int bef=0;
     95         memset(pre,-1,sizeof(pre));
     96         scanf("%d%d",&n,&m);
     97         for(int i=1;i<=n;i++)  scanf("%d",&a[i]);
     98         rot[n+1] = build(1,n);
     99         for(int i=n;i>0;i--)
    100         {
    101             if(pre[a[i]] == -1)  rot[i] = update(rot[i+1],i,1);
    102             else
    103             {
    104                 int tmp = update(rot[i+1],pre[a[i]],-1);
    105                 rot[i] = update(tmp,i,1);
    106             }
    107             pre[a[i]] = i ;
    108         }
    109         printf("Case #%d:",++kase);
    110         while(m--)
    111         {
    112             int l,r;
    113             scanf("%d%d",&l,&r);
    114             int ll = (l + bef)%n + 1;
    115             int rr = (r + bef)%n + 1;
    116             l = min(ll, rr);
    117             r = max(ll, rr);
    118             int k = query(l,r,1,n,rot[l]);
    119             k = ceil(k/2.0);
    120             int ans = calc(1,n,k,rot[l]);
    121             bef = ans;
    122             printf(" %d",ans);
    123         }
    124         puts("");
    125     }
    126     return 0;
    127 }
  • 相关阅读:
    LeetCode 230. Kth Smallest Element in a BST
    LeetCode 114. Flatten Binary Tree to Linked List
    LeetCode 222. Count Complete Tree Nodes
    LeetCode 129. Sum Root to Leaf Numbers
    LeetCode 113. Path Sum II
    LeetCode 257. Binary Tree Paths
    Java Convert String & Int
    Java Annotations
    LeetCode 236. Lowest Common Ancestor of a Binary Tree
    LeetCode 235. Lowest Common Ancestor of a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7674325.html
Copyright © 2011-2022 走看看