zoukankan      html  css  js  c++  java
  • luogu P4422 题解

    Solution

    题目

    看到题目中 (2 leq n leq 2 imes 10 ^ 5)(1 leq x,y leq 10 ^ 9) 和空间的 ( ext{62.5MB}) 这提示了我们要按年龄建树,否则就算你写动态开点线段树也会 ( ext{MLE})

    首先,根据年龄,建一棵线段树,之后对于小马里卡的话,对线段树进行单点修改,并且向上修改区间最小值即可。

    如果是爷爷的话,可以理解为求区间 ([B,N]) 之间下车的地方大于 (Y) 的最小值。

    这样的话我们在查询的时候,就可以按照以下思路查询 :

    • 当整个区间都在左子树,递归搜索左子树,如果左子树的下车位置的最小值大于 (Y) 直接返回。
    • 当整个区间都在左子树,递归搜索右子树,如果右子树的下车位置的最小值大于 (Y) 直接返回。
    • 当区间一部分在左子树,一部分在右子树,那么先搜索左子树,再搜索右子树,因为我们要保证年龄最小,如果下车位置最小值小于等于 (Y) 搜索左子树,如果发现没有搜到结果,同理,再搜索右子树。
    • 如果当前是一个叶子结点,更新答案,取最小值。

    如果有一部分在左子树,一部分在右子树,查询右子树的时候要先判断是否答案已经被更新过,如果更新过就不用搜索了,否则会超时。

    还有就是一开始整棵树的最小值都要赋值为 INF。

    Code

    #include <cstdio>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #define INF 0x3f3f3f3f 
    using namespace std;
    const int Maxk = 2e6 + 10;
    struct SegTree {
      int l,r,min_;
    }t[Maxk << 2];
    int n,m,cnt,Ans;
    inline int read()
    {
    	int s = 0, f = 0;char ch = getchar();
    	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
    	return f ? -s : s;
    }
    void build(int i,int l,int r)
    {
      t[i].l = l;
      t[i].r = r;
      t[i].min_ = INF;
      if(l == r) {
        t[i].min_ = INF;
        return;
      }
      int mid = (l + r) >> 1;
      build(i << 1,l,mid);
      build(i << 1 | 1,mid + 1,r);
    }
    void Add(int i,int pos,int k)
    {
      if(t[i].l == t[i].r && pos == t[i].l) {
        t[i].min_ = k;
        return;
      } 
      int mid = (t[i].l + t[i].r) >> 1;
      if(pos <= mid) Add(i << 1,pos,k);
      else Add(i << 1 | 1,pos,k);
      t[i].min_ = min(t[i << 1].min_,t[i << 1 | 1].min_);
    }
    void Ask(int i,int l,int r,int k)
    {
      if(t[i].l == t[i].r) {Ans = min(Ans,t[i].l);return;}
      int mid = (t[i].l + t[i].r) >> 1;
      if(r < mid) {//整个区间要求的的区间都在这个区间的左边 
        if(t[i << 1].min_ > k) return;
        else Ask(i << 1,l,r,k); 
      }
      else if(l > mid) {
        if(t[i << 1 | 1].min_ > k) return;
        else if(Ans == INF) Ask(i << 1 | 1,l,r,k);
      }
      else {
        if(t[i << 1].min_ <= k) Ask(i << 1,l,r,k);
        if(t[i << 1 | 1].min_ <= k && Ans == INF) Ask(i << 1 | 1,l,r,k);
      } 
      return;
    } 
    signed main()
    {
      n = read(),m = read();
      build(1,1,n);
      for(int i = 1;i <= m;i ++) {
        char c;cin >> c;
        if(c == 'M') {
          int x = read(),A = read();
          Add(1,A,x);
        }
        else {
          int y = read(),b = read();
          Ans = INF;Ask(1,b,n,y);
          printf("%d
    ",Ans == INF ? -1 : Ans);
        }
      }
      return 0;
    }
    
  • 相关阅读:
    团队项目推荐:附近商家无地图导航——by Manni
    团队项目推荐:基于社交网络的自动音乐推荐系统——by ZhongXia
    往届项目回顾:自动字幕对轴软件Autosub
    【Daily Scrum】11-19
    【Review】Review of Sprint 1& Sprint 2 planning
    【Daily Scrum】11-17 Summary of Sprint 1
    【Daily Scrum】11-13
    【Daily Scrum】11-12
    【Daily Scrum】11-11
    【Daily Scrum】11-7
  • 原文地址:https://www.cnblogs.com/Ti-despair/p/15028604.html
Copyright © 2011-2022 走看看