• 老瞎眼 pk 小鲜肉 (线段树)


    链接:https://ac.nowcoder.com/acm/contest/1114/E
    来源:牛客网

    题目描述

    老瞎眼有一个长度为 n 的数组 a,为了为难小鲜肉,他准备了 Q 次询问,每次给出 一个区间[L,R],他让小鲜肉寻 找一对 l,r 使L<=l<=r<=R 且 a[l]^a[l+1]^a[l+2]...^a[r]=0,老瞎眼只让他回答r-l+1 最小是多少,若没有符合条件的 l,r 输出”-1”。 

    输入描述:

    第一行输入 n,Q。
    第二行输入 n 个数,表示 a 数组。
    接下来 Q 行,每行输入 L,R。
    1<=n,Q<=500000,0<=a[i]<=1000000,1<=L<=R<=n

    输出描述:

    若有解,输出 r-l+1 最小是多少。
    否则输出“-1”。
    示例1

    输入

    4 2
    2 1 3 3
    1 2
    1 3

    输出

    -1
    3

    说明

    第一次询问无解。
    第二次询问:
    l=1,r=3

    析:根据题意,我们可以使用O(n),或者是O(nlogn)来求出以 a[i] 右边界的的左边界在哪,然后把所有的询问离线,按照右端点从小到大排序,维护一个棵线段树,结点代表以 i 为右边界的最小区间长度,对于每个询问,只要把所有的右端点前的值更新到线段树中,再查询一次最小值即可知道答案。

    代码如下:

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #include <set>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <cctype>
    #include <cmath>
    #include <stack>
    #include <sstream>
    #include <list>
    #include <assert.h>
    #include <bitset>
    #include <numeric>
    #define debug() puts("++++")
    #define gcd(a, b) __gcd(a, b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a, b, sizeof a)
    #define sz size()
    #define be begin()
    #define ed end()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define FOR(i,n,x)  for(int i = (x); i < (n); ++i)
    #define freopenr freopen("in.in", "r", stdin)
    #define freopenw freopen("out.out", "w", stdout)
    using namespace std;
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int, int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e17;
    const double inf = 1e20;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int maxn = 5e5 + 7;
    const int maxm = 2000000 + 7;
    const LL mod = 1e9 + 7;
    const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1};
    const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1};
    const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
    int n, m;
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    inline bool is_in(int r, int c) {
      return r >= 0 && r < n && c >= 0 && c < m;
    }
    inline int readInt(){ int x;  scanf("%d", &x);  return x; }
    
    int a[maxn];
    
    int sum[maxn<<2];
    
    void update(int M, int val, int l, int r, int rt){
      if(l == r){
        sum[rt] = val;
        return ;
      }
      int m = l + r >> 1;
      if(M <= m)  update(M, val, lson);
      else  update(M, val, rson);
      sum[rt] = min(sum[rt<<1], sum[rt<<1|1]);
    }
    
    int query(int L, int R, int l, int r, int rt){
      if(L <= l && r <= R)  return sum[rt];
      int ans = INF;
      int m = l + r >> 1;
      if(L <= m)  ans = query(L, R, lson);
      if(R > m)  ans = min(ans, query(L, R, rson));
      return ans;
    }
    
    struct Query{
      int id, l, r;
    };
    int ans[maxn];
    Query q[maxn];
    
    int main(){
      scanf("%d %d", &n, &m);
      ms(sum, INF);
      int sum = 0;
      map<int, int> mp;  mp[0] = 1;
      ms(a, INF);
      for(int i = 1; i <= n; ++i){
        int x;  scanf("%d", &x);
        sum ^= x;
        int y = mp[sum];
        if(y != 0)  a[i] = y;
        mp[sum] = i+1;
      }
      for(int i = 0; i < m; ++i){
        q[i].id = i;
        scanf("%d %d", &q[i].l, &q[i].r);
      }
      sort(q, q + m, [&](Query q1, Query q2){ return q1.r < q2.r; });
      int x = 1;
      for(int i = 0; i < m; ++i){
        while(x <= q[i].r){
          if(a[x] != INF)  update(a[x], x-a[x]+1, all);
          ++x;
        }
        int res = query(q[i].l, q[i].r, all);
        ans[q[i].id] = res == INF ? -1 : res;
      }
      for(int i = 0; i < m; ++i)  printf("%d
    ", ans[i]);
      return 0;
    }
    

      

      

  • 相关阅读:
    ios-UIScrollView-常用属性和方法
    ios-后台运行UIApplication
    ios-UIImage写入相册
    ios-时间格式化
    ios-block-对象与对象之间的解偶合
    ios-通知
    Copy List with Random Pointer
    leetcode面试频率
    TCP的连接(三次握手)和释放(四次挥手)
    Longest Palindromic Substring(字符串的最大回文子串)
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/11817174.html
Copyright © 2020-2023  润新知