【dp+離散化+線段樹優化】Paint

CN_swords發表於2017-08-25

題意: 求不相交的區間集合,沒有覆蓋到的範圍最小

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 4e5+10;
const int M = 26;
const int INF = 0x3f3f3f3f;

vector<LL> xs;
inline int getid(LL x){return lower_bound(xs.begin(),xs.end(), x) - xs.begin() + 1;}

struct asd{
    LL l,r;
    LL sum;
}a[N];
bool cmp(asd x,asd y){
    if(x.l != y.l) return x.l < y.l;
    return x.r < y.r;
}

struct Node{
    int left,right;
    LL maxn;
}node[N*4];
int father[N*4];

void BulitTree(int i,int l,int r){
    node[i].left = l;
    node[i].right = r;
    node[i].maxn = 0;
    if(l == r){
        father[l] = i;
        return ;
    }
    BulitTree(i*2,l,(l+r)/2);
    BulitTree(i*2+1,(l+r)/2+1,r);
}

void Update(int i){
    if(i == 1)  return ;
    int pi = i/2;
    LL x = node[pi*2].maxn;
    LL y = node[pi*2+1].maxn;
    node[pi].maxn = max(x,y);
    Update(pi);
}

LL ans;
void Query(int i,int l,int r){
    if(node[i].right==r && node[i].left==l){
        ans = max(ans,node[i].maxn);
        return ;
    }
    i = i*2;
    if(l <= node[i].right){
        if(r <= node[i].right){
            Query(i,l,r);
        }
        else{
            Query(i,l,node[i].right);
        }
    }
    i++;
    if(r >= node[i].left){
        if(l >= node[i].left)
            Query(i,l,r);
        else
            Query(i,node[i].left,r);
    }
}

int main(){
    LL n;
    int m;
    scanf("%lld%d",&n,&m);
    BulitTree(1,1,m*2+1);
    for(int i = 1; i <= m; i++){
        scanf("%I64d%I64d",&a[i].l,&a[i].r);
        a[i].sum = a[i].r-a[i].l+1;
    }
    sort(a+1,a+m+1,cmp);
    xs.push_back(0);
    for(int i = 1; i <= m; i++)
    {
        xs.push_back(a[i].l);
        xs.push_back(a[i].r);
    }
    sort(xs.begin(), xs.end());
    vector<LL>::iterator e;
    e=unique(xs.begin(),xs.end());
    xs.erase(unique(xs.begin(), xs.end()) , xs.end());

    int id = getid(0);
    int x = father[id];
    node[x].maxn = 0;
    Update(x);
    for(int i = 1; i <= m; i++){
        id = getid(a[i].l);
        ans = 0;
        Query(1,1,id-1);

        id = getid(a[i].r);
        x = father[id];
        node[x].maxn = ans+a[i].sum;
        Update(x);
    }
    ans = 0;
    Query(1,1,m*2+1);
    printf("%I64d\n",n-ans);
    return 0;
}


相關文章