写在前面的话
蒟蒻流下了不学无术的眼泪,英语不好是真的硬伤,蒟蒻在巨佬的提示下才勉强明白了题意
题意
你有条按顺序(很重要!)给出的线段,要求你使用最少的线段覆盖
。另外在你选择一条线段时你必须保证你的前置线段已全部被覆盖。
思路
我们可以定义为前
个排序器将第
个数提到
所需要的最少的排序器的数量,那么当
的时候
当
的时候
,我们状态数有
个,显然是会
飞的结果啊。所以考虑使用线段树来优化一下就好。
代码
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <typeinfo>
#include <vector>
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
const int N=1e5+5,INF=0x3f3f3f3f;
using namespace std;
int n,m;
struct segment
{
int l,r,x;
}seg[N<<2];
inline int read()
{
register int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*f;
}
void build(int rt,int l,int r)
{
seg[rt].l=l;seg[rt].r=r;
if(l == r)
{
int val=INF;
if(l == 1) val=0;
seg[rt].x=val;
return ;
}
int mid=(l+r)/2;
build(lson,l,mid);
build(rson,mid+1,r);
seg[rt].x=min(seg[lson].x,seg[rson].x);
}
int query(int rt, int l, int r)
{
if(seg[rt].l==l&&seg[rt].r==r)
return seg[rt].x;
int mid=(seg[rt].l+seg[rt].r)/2;
if(r<=mid)
return query(lson,l,r);
else if(l>mid)
return query(rson,l,r);
else
{
int v1=query(lson,l,mid);
int v2=query(rson,mid+1,r);
return min(v1,v2);
}
}
void update(int rt, int i, int c)
{
if(seg[rt].l==seg[rt].r&&seg[rt].l==i)
{
seg[rt].x=c;
return ;
}
int mid=(seg[rt].l+seg[rt].r)/2;
if(i<=mid)
update(lson,i,c);
else
update(rson,i,c);
seg[rt].x=min(seg[lson].x,seg[rson].x);
}
int main()
{
n=read();m=read();
build(1,1,n);
for(int i=1;i<=m;i++)
{
int s,t;
s=read();t=read();
int v=min(query(1,s,t)+1,query(1,t,t));
update(1,t,v);
}
printf("%d",query(1,n,n));
return 0;
}
写在后面的话
为什么不支持万能头这么好的东西 TAT

京公网安备 11010502036488号