码迷,mamicode.com
首页 > 其他好文 > 详细

P3740 [HAOI2014]贴海报

时间:2020-02-25 20:12:07      阅读:42      评论:0      收藏:0      [点我收藏+]

标签:之间   alt   space   左右   open   clu   https   cli   节点   

----------------------------

链接:Miku

----------------------------

这道题比想象的要水,虽然说标签有个离散化,但是事实上根本不用

但是这道题的空间范围很苛刻,倘若写记录每个点的左右子节点的线段树写法的话,可能会MLE

所以我写了不记录的写法,这样虽然会牺牲时间,但是节省了空间

而且这道题的空间,竟然开n*3就可以了

----------------------------

思路:海报之间是没有区别的,暴力的思路就是正着贴,最后计算一下露出来的种类就可以了

(虽然似乎也能够过)

但是其实可以倒着做,因为后面的如果能,就一定能覆盖前面的,这样的话我们就倒着贴每一张,然后看一下这一张的位置里

还有没有空,有空就贴上

怎样快速知道有没有空呢?每一个格子,如果贴上了,就标记为1,反之为0,这样我们求出来区间的和,与区间长度进行一下比较,就可以了,

如果有空,就把整个区间覆盖为1,(反正海报之间没有区别),然后ans++即可

----------------------------

区间覆盖+区间求和可以做一下这道题

-------------------------------

技术图片
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
long long sum[30000005], lazy[30000005];
int f,x,y;
long long k;
int ans;
int ll[1001],rr[1001]; 
void pushdown(int x, int L, int R){
    if (lazy[x] != 0){
        int mid = (L + R) >> 1;
        lazy[x << 1] = lazy[x];
        lazy[x << 1 | 1] = lazy[x];
        sum[x << 1] = lazy[x] * (mid - L + 1);
        sum[x << 1 | 1] = lazy[x] * (R - mid);
        lazy[x] = 0;
    }
    return;
}
void pushup(int x){
    sum[x] = sum[x << 1] + sum[x << 1 | 1];
    return;
}
void update(int x, int l, int r, int L, int R, long long d){
    if (L <= l && r <= R){
        lazy[x] =d;
        sum[x] = d * (r - l + 1);
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(x, l, r);
    if (L <= mid) update(x << 1, l, mid, L, R, d);
    if (R > mid) update(x << 1 | 1, mid + 1, r, L, R, d);
    pushup(x);
}
long long query(int x, int l, int r, int L, int R){
    if (L <= l && r <= R){
        return sum[x];
    }
    int mid = (l + r) >> 1;
    pushdown(x, l, r);
    long long ans = 0;
    if (L <= mid) ans += query(x << 1, l, mid, L, R);
    if (R > mid) ans += query(x << 1 | 1, mid + 1, r, L, R);
    return ans;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i){
        cin>>ll[i]>>rr[i]; 
    }
    for(int i=m;i>=1;--i){
            x=ll[i];
            y=rr[i];
            if(query(1,1,n,x,y)<y-x+1){
            update(1, 1, n, x, y,1);
            ans++;
            }
    }
    cout<<ans;
    return 0;
}
Ac

 

P3740 [HAOI2014]贴海报

标签:之间   alt   space   左右   open   clu   https   cli   节点   

原文地址:https://www.cnblogs.com/For-Miku/p/12363252.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!