写在卸载之前
表明参考出处一位dalao
正式开始
对于一道题分析
可以使用线段树进行区间覆盖
但是这里的话一位大佬提出使用并查集想法
首先 我们固定左端点
然后 不断移动右端点
当然 朴素的写肯定会挂
我们发现 每一次朴素移动的话浪费时间就是因为已被删除元素被重复删除
所以我们使用并查集来维护这个元素左边最靠右的没有被删除元素的位置
然后每次移动的通过并查集直接移动到未被删除元素上 从而保证时间复杂度
CODE:
#include<bits/stdc++.h>
#define M 1008611
using namespace std;
int n,m,cnt;
int bel[M];
int find(int x)
{return bel[x]==x ? x:bel[x]=find(bel[x]);}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<=n+1;++i) bel[i]=i;
for(int i=1,x,y;i<=m;++i)
{
scanf("%d%d",&x,&y);
y=find(y);
while(x<=y)
{
if(x!=y&&find(x)==find(y)) break;//如果已经是都被删除了
bel[y]=find(bel[y-1]);//向左合并 维护未被删除元素的位置
++cnt;//维护已被删除的熟练
y=find(y);//向左移动 由于使用了并查集 所以这样移动的话累积下来是O(n)复杂度
}
printf("%d\n",n-cnt);
}
return 0;
}