zoukankan      html  css  js  c++  java
  • hdu 6703 array 权值线段树

    题目读了半天没读懂......

    给你一个长度为n的排列a。两种操作,每次把里面的某个数增加10,000,000,或者询问不等于a1-ar,且不小于k的最小的数是多少。k不超过n。所以答案必定不超过n+1。

    我们考虑对原序列做权值线段树,下标为原序列的值,值为原序列的下标。

    先考虑没有修改,那么不小于k就是只从线段树下标为[k + 1,n + 1]的范围找答案。不等于a1-ar就是线段树的值(原序列下标)要大于r。要最小的数,就是能往左子树找就往左子树找。

    考虑修改,某个数ai增加了10,000,000,则意味着,原先ai这个数,再也不会被a1-ar这个条件限制了,因为a是一个排列,ai独此一份,现在被改成了个很大的数。所以干脆把线段树下标ai对应的值改成n+1,这样子,就再也不会受a1-ar这个条件限制了。

    复杂度是mlogn,直观感受下就是,不再范围内的部分,发现出界会立马停止。在范围内的部分,只有一条会递归到底,一共两条,所是logn。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cmath>
     5 using namespace std;
     6 const int MAXN = 101000;
     7 int n,m,T,vec[MAXN],a[MAXN];
     8 struct segtree
     9 {
    10     int maxn[4 * MAXN]; 
    11     void build(int k,int l,int r,int *vec)
    12     {
    13         if (l == r)
    14         {
    15             maxn[k] = vec[l];
    16             return;
    17         }
    18         int mid = l + r >> 1;
    19         build(k << 1,l,mid,vec);
    20         build(k << 1 | 1,mid + 1,r,vec);
    21         maxn[k] = max(maxn[k << 1],maxn[k << 1 | 1]);
    22     }
    23     void change(int k,int l,int r,int x)
    24     {
    25         if (l == r)
    26         {
    27             maxn[k] = n + 1;
    28             return;
    29         }
    30         int mid = l + r >> 1;
    31         if (x <= mid)
    32             change(k << 1,l,mid,x);
    33         else
    34             change(k << 1 | 1,mid + 1,r,x);
    35         maxn[k] = max(maxn[k << 1],maxn[k << 1 | 1]);
    36     }
    37     int query(int k,int l,int r,int x,int y)
    38     {
    39         if (r < y)
    40             return -1;
    41         if (l == r)
    42             return l;
    43         int mid = l + r >> 1,res = -1;
    44         if (maxn[k << 1] > x)
    45             res = query(k << 1,l,mid,x,y);
    46         if (res == -1)
    47             if (maxn[k << 1 | 1] > x)
    48                 res = query(k << 1 | 1,mid + 1,r,x,y);
    49         return res;
    50     }
    51 } st;
    52 int main()
    53 {
    54     for (scanf("%d",&T);T != 0;T--)
    55     {
    56         
    57         int lst = 0;
    58         scanf("%d%d",&n,&m);
    59         for (int i = 1;i <= n;i++)
    60         {
    61             scanf("%d",&a[i]);
    62             vec[a[i]] = i;
    63         }
    64         vec[n + 1] = n + 1;
    65         st.build(1,1,n + 1,vec);
    66         int tx,ty,opt;
    67         for (int i = 1;i <= m;i++)
    68         {
    69             scanf("%d",&opt);
    70             if (opt == 1)
    71             {
    72                 scanf("%d",&tx);
    73                 tx ^= lst;
    74                 st.change(1,1,n + 1,a[tx]);
    75             }else
    76             {
    77                 scanf("%d%d",&tx,&ty);
    78                 tx ^= lst;
    79                 ty ^= lst;
    80                 lst = st.query(1,1,n + 1,tx,ty);
    81                 printf("%d
    ",lst); 
    82             }
    83         }
    84     }
    85 }
    心之所动 且就随缘去吧
  • 相关阅读:
    Selenium之IE浏览器的启动问题及解决
    Selenium之Chrome浏览器的启动问题及解决
    Selenium之IE浏览器的启动
    Selenium之firefox浏览器的启动
    【luogu 3373】【模板】线段树2
    【luogu 3372】【模板】线段树1
    【luogu 1908】逆序对
    【codevs2822】爱在心中
    【bzoj1051】 [HAOI2006]受欢迎的牛
    【luogu 2863】[USACO06JAN]牛的舞会The Cow Prom
  • 原文地址:https://www.cnblogs.com/iat14/p/11404869.html
Copyright © 2011-2022 走看看