这是P3084的AC代码。有些地方对着题解打的,轻点喷谢谢。
//writer:Oier_szc
#include <bits/stdc++.h>
#define TS puts("I AK IOI");
//#define int long long
using namespace std;
const int N=1e5+5,M=2e5+5;
int n,m,ans=-1;
struct node
{
int l,r;
}a[N];
int maxl[M],minl[M];
int f[M];
int q[M],hh=0,tt=0;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n+1;++i) minl[i]=i-1;
for(int i=1;i<=m;++i)
{
scanf("%d%d",&a[i].l,&a[i].r);
minl[a[i].r]=min(minl[a[i].r],a[i].l-1);
maxl[a[i].r+1]=max(maxl[a[i].r+1],a[i].l);
}
for(int i=n;i>=1;--i)
{
minl[i]=min(minl[i],minl[i+1]);
}
for(int i=2;i<=n+1;++i)
{
maxl[i]=max(maxl[i],maxl[i-1]);
}
int now=1;
for(int i=1;i<=n+1;++i)
{
while(now<=n&&now<=minl[i])
{
if(f[now]==-1)
{
++now;
continue;
}
while(hh<=tt&&f[now]>f[q[tt]]) --tt;
q[++tt]=now;
++now;
}
while(hh<=tt&&q[hh]<maxl[i]) ++hh;
//cout<<i<<" "<<hh<<" "<<tt<<" "<<now<<endl;
if(hh<=tt)
{
f[i]=f[q[hh]]+(i!=n+1?1:0);
}
else f[i]=-1;
}
printf("%d\n",f[n+1]);
return 0;
}
考虑调换加入元素和弹出元素的执行顺序,变成这样。
//writer:Oier_szc
#include <bits/stdc++.h>
#define TS puts("I AK IOI");
//#define int long long
using namespace std;
const int N=1e5+5,M=2e5+5;
int n,m,ans=-1;
struct node
{
int l,r;
}a[N];
int maxl[M],minl[M];
int f[M];
int q[M],hh=0,tt=0;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n+1;++i) minl[i]=i-1;
for(int i=1;i<=m;++i)
{
scanf("%d%d",&a[i].l,&a[i].r);
minl[a[i].r]=min(minl[a[i].r],a[i].l-1);
maxl[a[i].r+1]=max(maxl[a[i].r+1],a[i].l);
}
for(int i=n;i>=1;--i)
{
minl[i]=min(minl[i],minl[i+1]);
}
for(int i=2;i<=n+1;++i)
{
maxl[i]=max(maxl[i],maxl[i-1]);
}
int now=1;
for(int i=1;i<=n+1;++i)
{
while(hh<=tt&&q[hh]<maxl[i]) ++hh;
while(now<=n&&now<=minl[i])
{
if(f[now]==-1)
{
++now;
continue;
}
while(hh<=tt&&f[now]>f[q[tt]]) --tt;
q[++tt]=now;
++now;
}
//cout<<i<<" "<<hh<<" "<<tt<<" "<<now<<endl;
if(hh<=tt)
{
f[i]=f[q[hh]]+(i!=n+1?1:0);
}
else f[i]=-1;
}
printf("%d\n",f[n+1]);
return 0;
}
然后样例输出2,答案是1。
已经不止一次遇到过该情况,至今不知道原因。希望dalao解答。如果这个问题很显然的话请大声呵斥SZC的蒻。