uva11983扫描线k次覆盖

自己做的是从下往上扫描的,一直wa,不知道坑在哪里。。但是作为模板。我还是找了份不错的ac代码

/*
被覆盖不低于k次的点
每个点对应了一个单位面积,本题把点转面积即是被覆盖不低于k次的面积
可以当做求k次面积覆盖模板的题目!
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map> 
using namespace std;
#define maxn 60005
#define lson l,m,rt<<1
#define rson m,r,rt<<1|1
#define ll long long
int n,k;
struct Seg{
    int l,r,h,c;
    Seg(){}
    Seg(int l,int r,int h,int c):l(l),r(r),h(h),c(c){}
    bool operator<(const Seg& a)const {
        return h<a.h;
    }
}segs[maxn];
int tot,totx,x[maxn];//线段树建立在x轴上
int len[maxn<<2][12],flag[maxn<<2];
map<int,int>mp;

inline void pushup(int rt,int l,int r){
    if(flag[rt]>=k){
        for(int i=1;i<=k;i++) len[rt][i]=0;
        len[rt][k]=x[r]-x[l];
        
    }
    else if(flag[rt]>0){
        int cur=flag[rt];//当前区间覆盖次数
        for(int i=1;i<=k;i++) len[rt][i]=0;//先把当前区间所有覆盖情况置零
        len[rt][cur]=x[r]-x[l];
        if(l+1==r) return;

        for(int i=1;i<=k;i++){
            if(i+cur>=k) len[rt][k]+=len[rt<<1][i]+len[rt<<1|1][i];
            else len[rt][i+cur]+=len[rt<<1][i]+len[rt<<1|1][i];
        }
        for(int i=cur+1;i<=k;i++) 
            len[rt][cur]-=len[rt][i];
    }
    else {
        for(int i=1;i<=k;i++) len[rt][i]=0;
        if(l+1==r) return;
        for(int i=1;i<=k;i++)
            len[rt][i]=len[rt<<1][i]+len[rt<<1|1][i];
    }
}
void update(int L,int R,int c,int l,int r,int rt){
    if(L<=l && R>=r){
        flag[rt]+=c;;
        pushup(rt,l,r);
        return;
    }
    int m=l+r>>1;
    if(L<m) update(L,R,c,lson);
    if(R>m) update(L,R,c,rson);
    pushup(rt,l,r);
}

void init(){
    tot=totx=0;
    mp.clear();
    memset(len,0,sizeof len);
    memset(flag,0,sizeof flag);
}
int main(){
    int T,a,b,c,d;
    cin >> T;
    for(int tt=1;tt<=T;tt++){
        init();
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++){
            scanf("%d%d%d%d",&a,&b,&c,&d);
            c++;d++;
            segs[tot++]=Seg(a,c,b,1);
            segs[tot++]=Seg(a,c,d,-1);
            x[totx++]=a;x[totx++]=c;
        }
        sort(x,x+totx);
        sort(segs,segs+tot);
        totx=unique(x,x+totx)-x;
        for(int i=0;i<totx;i++) mp[x[i]]=i;

        ll res=0;
        for(int i=0;i<tot;i++){
            if(i!=0) 
                res+=(segs[i].h-segs[i-1].h)*len[1][k];
            //  cout<<segs[i].h-segs[i-1].h<< " "<<len[1][k]<<'
';
            update(mp[segs[i].l],mp[segs[i].r],segs[i].c,0,totx-1,1);

        }
        printf("Case %d: %lld
",tt,res);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zsben991126/p/9964423.html