AtCoder Beginner Contest 103 - D Islands War (贪心)

题目

题意:

给你n个点,他们1到n依次从左到右连接。问你m对数(A,B)。AB不能相连。

问你最少要拆多少条边.

POINT:

R端点从左到右排序。然后看看L到R有没有拆至少一条边,有的话就不用拆了。

没有的话拆R这个点的边。

看L到R有没有拆边可以用树状数组实现log(N)的效率。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <map>
using namespace std;
#define LL long long
const int maxn = 1e6+33;
const int mod = 1e9+7;

int num[maxn];

struct node
{
    int l,r;
    bool friend operator < (node a,node b){
        return a.r<b.r;
    }
}q[maxn];
int n,m;
void add(int x,int p)
{
    for(int i=x;i<=n;i+=i&-i)
        num[i]+=p;
}

int query(int x)
{
    int ans=0;
    for(int i=x;i>=1;i-=i&-i){
        ans+=num[i];
    }
    return ans;
}


int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&q[i].l,&q[i].r);
    }
    sort(q+1,q+1+m);
    int ans=0;
    for(int i=1;i<=m;i++){
        int to = query(q[i].r)-query(q[i].l);
        if(to==0){
            add(q[i].r,1);
            ans++;
        }
    }
    printf("%d\n",ans);
    return 0;

}

猜你喜欢

转载自blog.csdn.net/mr_treeeee/article/details/81154015
今日推荐