zoukankan      html  css  js  c++  java
  • 线段树区间覆盖 蛤玮打扫教室(zzuli 1877)

    http://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1877

     

     

    Description

     

     

     

    现在知道一共有n个机房,算上蛤玮一共有m个队员,教练做了m个签,每个签上写着两个数L,R(L<=R),抽到的人要把[L,R]的教室全部打扫一遍.由于蛤玮是队长而且他很懒,他通过某种交易提前知道了所有m个签上面写的是什么,而且通过某种魔法可以控制自己抽到哪个签.一个教室被打扫一次就干净了,所以蛤玮想知道自己抽哪些签可以不用打扫教室而且不会被教练发现,即他抽到的区间全都会被别人打扫一遍.
     

     

     

    蛤玮被教练叫去打扫机房,集训队有很多机房,也有很多队员,现在他们要用抽签的方式决定谁打扫哪间教室.

    Input

    第一行为一个整数T(1<=T<=20),代表数据组数。每组数据第一行n,m(1<=n,m<=100000),接下来m行,每行两个数L,R(1<=L<=R<=n).

     

    Output

    每组数据输出一个k,表示多少个签符合蛤玮的要求,接下来一行输出k个数,这些签的编号,下标从1开始.

     

    Sample Input

    3 15 5 1 4 5 5 6 8 9 10 5 6 3 6 1 1 1 1 2 2 2 2 3 3 3 3 10 3 1 4 2 6 6 10

    Sample Output

    2 2 5 6 1 2 3 4 5 6 0
     
    2016轻院校赛失之交臂的题呀!!!
     
     
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<math.h>
    using namespace std;
    
    #define EPS 1e-6
    #define N 110000
    #define met(a,b) (memset(a,b,sizeof(a)))
    #define Lson r<<1
    #define Rson r<<1|1
    
    struct E
    {
        int L, R;
    }a[N];
    
    int v[N];
    
    struct node
    {
        int L, R, x;
        int mid()
        {
            return (L+R)/2;
        }
        int len()
        {
            return (R-L+1);
        }
    }Tree[N<<2];
    
    void BuildTree(int r, int L, int R)
    {
        Tree[r].L = L, Tree[r].R = R, Tree[r].x = 0;
    
        if(L==R)
            return ;
    
        BuildTree(Lson, L, Tree[r].mid());
        BuildTree(Rson, Tree[r].mid()+1, R);
    }
    
    void Update(int r, int L, int R)
    {
        if(Tree[r].L==L && Tree[r].R==R)
        {
            Tree[r].x++;
            return ;
        }
    
        if(R<=Tree[r].mid())
            Update(Lson, L, R);
        else if(L>Tree[r].mid())
            Update(Rson, L, R);
        else
        {
            Update(Lson, L, Tree[r].mid());
            Update(Rson, Tree[r].mid()+1, R);
        }
    }
    
    void Up(int r, int L, int R)
    {
        if(L==R)
            return ;
    
        Tree[Lson].x += Tree[r].x;
        Tree[Rson].x += Tree[r].x;
    
        Up(Lson, L, Tree[r].mid());
        Up(Rson, Tree[r].mid()+1, R);
    
        Tree[r].x = min(Tree[Lson].x, Tree[Rson].x);
    }
    
    int Query(int r, int L, int R)
    {
        if(Tree[r].L==L && Tree[r].R==R)
            return Tree[r].x;
    
        if(R<=Tree[r].mid())
            return Query(Lson, L, R);
        else if(L>Tree[r].mid())
            return Query(Rson, L, R);
        else
            return min(Query(Lson, L, Tree[r].mid()), Query(Rson, Tree[r].mid()+1, R));
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int n, m, i, k=0, ans;
    
            scanf("%d%d", &n, &m);
    
            met(a,0);
            met(v,0);
            BuildTree(1, 1, n);
    
            for(i=1; i<=m; i++)
            {
                scanf("%d%d", &a[i].L, &a[i].R);
                Update(1, a[i].L, a[i].R);
            }
    
            Up(1, 1, n);
    
            for(i=1; i<=m; i++)
            {
                ans = Query(1, a[i].L, a[i].R);
                if(ans>=2)
                    v[k++] = i;
            }
    
            printf("%d
    ", k);
            for(i=0; i<k; i++)
                printf("%d%c", v[i], i==k-1?'
    ':' ');
    
        }
        return 0;
    }
     关于区间覆盖很巧妙地一种用法, 跟之前写的有个涂气球的有个题, 思想是相同的, 这次记下, 以后定有用处
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<math.h>
    using namespace std;
    
    #define EPS 1e-6
    #define N 110000
    #define met(a,b) (memset(a,b,sizeof(a)))
    
    struct node
    {
        int L, R;
    }a[N];
    
    int v[N], w[N], sum[N], b[N];
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int n, m, i, s=0, k=0;
    
            scanf("%d%d", &n, &m);
            met(v, 0);
            met(sum, 0);
            met(w, 0);
            met(b, 0);
    
            for(i=1; i<=m; i++)
            {
                scanf("%d%d", &a[i].L, &a[i].R);
                v[a[i].L]++;
                v[a[i].R+1]--;
            }
    
            for(i=0; i<=n; i++)
            {
                s += v[i];
                w[i] = s;
            }
    
            for(i=0; i<=n; i++)
            {
                if(w[i]>=2) sum[i] = sum[i-1]+1;
                else  sum[i] = sum[i-1];
            }
    
            for(i=1; i<=m; i++)
            {
                if(sum[a[i].R]-sum[a[i].L-1]==a[i].R-a[i].L+1)
                  b[k++] = i;
            }
    
            printf("%d
    ", k);
            for(i=0; i<k; i++)
                printf("%d%c", b[i], i==k-1?'
    ':' ');
        }
        return 0;
    }
    勿忘初心
  • 相关阅读:
    1082 射击比赛 (20 分)
    1091 N-自守数 (15 分)
    1064 朋友数 (20 分)
    1031 查验身份证 (15 分)
    1028 人口普查 (20 分)
    1059 C语言竞赛 (20 分)
    1083 是否存在相等的差 (20 分)
    1077 互评成绩计算 (20 分)
    792. 高精度减法
    791. 高精度加法
  • 原文地址:https://www.cnblogs.com/YY56/p/5405506.html
Copyright © 2011-2022 走看看