zoukankan      html  css  js  c++  java
  • 牛客网暑期ACM多校训练营(第六场) I Team Rocket(线段树)

    题意:

    给定n个区间, m次询问, 每次询问给一个点, 问这个点在哪些区间内, 然后删掉这些区间。

    分析:

    将n个区间按L大小升序排列, 然后将这些区间视为点构建一棵n个点的线段树, 树的节点记录这个区间的[l, r] 和按题目输入顺序排列的index

    只有叶子节点的l, r代表这个区间本身, 他们的父亲更新他们儿子的最大r用于剪枝 (如果这个点所有儿子的最大R都小于查询的点, 就不用查了)

    接下来只要二分出左区间大于x的那个区间的pos, 那么查询区间就是(1~pos)中有哪些点的右区间大于x, 记录答案并修改右区间即可。 

    #include <bits/stdc++.h>
    using namespace std;
    const int maxN = 2e5 + 7;
    const int INF = 2e9 + 7;
    int n, m, x, y, pos, t, cancel;
    long long res;
    int ans[maxN];
    struct Interval {
        int l, r, index;
        bool operator < (const Interval& a)const {
            return l < a.l;
        }
    } travel[maxN], tree[maxN * 4];
      
    void build(int treeIndex, int L, int R) {
    //    printf("%d %d
    ", L , R);
        if(L == R) {
            tree[treeIndex].l = travel[L].l;
            tree[treeIndex].r = travel[L].r;
            tree[treeIndex].index = travel[L].index;
            return;
        }
        int mid = (L + R) / 2;
        int lSon = treeIndex * 2, rSon = treeIndex * 2 + 1;
        build(lSon, L, mid);
        build(rSon, mid + 1, R);
        tree[treeIndex].r = max(tree[lSon].r, tree[rSon].r);
    }
      
    void query(int treeIndex, int L, int R) {
        if(tree[treeIndex].r < x)
            return;
        if(L == R) {
            cancel++;
            int inIndex = tree[treeIndex].index;
            res = ((long long)res * inIndex) % 998244353;
            tree[treeIndex].r = -INF;
            ans[inIndex] = t;
            return;
        }
         
        int mid = (L + R) / 2;
        int lSon = treeIndex * 2, rSon = treeIndex * 2 + 1;
        query(lSon, L, mid);
        if(pos > mid)
            query(rSon, mid + 1, R);
        tree[treeIndex].r = max(tree[lSon].r, tree[rSon].r);
    }
      
    int main() {
    //    freopen("data.txt","r", stdin);
    //    freopen("3.txt","w", stdout);
        int T;
        scanf("%d", &T);
        for(int kase = 1; kase <= T; kase++) {
            printf("Case #%d:
    ", kase);
            memset(ans, 0, sizeof(ans));
            memset(tree, 0, sizeof(tree));
            memset(travel, 0 , sizeof(travel));
            scanf("%d %d", &n, &m);
            for(int i = 1; i <= n; i++) {
                scanf("%d %d", &travel[i].l, &travel[i].r);
                travel[i].index = i;
            }
            sort(travel + 1, travel + 1 + n);
    //        for(int i = 1; i <= n; i++) printf("%d %d
    ", travel[i].l, travel[i].r);
            build(1, 1, n);
            res = 0;
            for(t = 1; t <= m; t++) {
                scanf("%d", &y);
                x = y ^ res;
                pos = upper_bound(travel + 1, travel + 1 + n, (Interval) {x,0,0}) - (travel + 1);
                cancel = 0, res = (long long)1;//乘积初始化为1
                if(pos > 0) // pos等于0说明没有任何一个左区间比x小
                    query(1, 1, n);//int treeIndex,  int L, int R
                printf("%d
    ", cancel);
                if(!cancel)
                    res = 0;
            }
      
      
      
            printf("%d", ans[1]);
            for(int i = 2; i <= n; i++) {
                printf(" %d", ans[i]);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Django的高级用法
    Django信号和缓存
    初识Django框架
    虚拟化之KVM(上)
    jQuery操作页面-day13
    SSM整合
    新闻发布系统
    jsp
    分层
    简单工厂
  • 原文地址:https://www.cnblogs.com/Jadon97/p/9432236.html
Copyright © 2011-2022 走看看