[AGC015E] Mr.Aoki Incubator 题解
我们考虑按照点的位置排序,容易发现,一个点可以染到的点是左侧他及他右侧最慢的快的点和右侧比他及他左侧最快的慢的点,进行一个简单的转化,也就相当于一个点可以被最靠左的满足速度不比他慢的点和最靠右的满足速度不比他快的点(显然这里包括他自己,所以不需要担心这一段区间都在左侧/右侧)。那么维护出来这\(n\)条线,就是一个简单的dp问题了。
#include <bits/stdc++.h>
#define int long long
#define lid tree[id].ls
#define rid tree[id].rs
#define mid ((l+r)>>1)
using namespace std;
const int maxn=2e5+10;
const int modd=1e9+7;
queue<int>s;
int n,l[maxn],r[maxn],dp[maxn],sum[maxn],xing,idd,rt;
vector<int>tu[maxn];
struct node{
int ls;
int rs;
int mn;
int mx;
}tree[maxn<<5];
struct edge{
int x;
int v;
}a[maxn];
int cmp(edge q,edge w){
return q.x<w.x;
}
void add(int &id,int l,int r,int q,int w){
if(!id){
idd++;
id=idd;
}
if(l==r){
tree[id].mn=min(tree[id].mn,w);
tree[id].mx=max(tree[id].mx,w);
return;
}
if(q<=mid){
add(lid,l,mid,q,w);
}
else{
add(rid,mid+1,r,q,w);
}
tree[id].mn=min(tree[lid].mn,tree[rid].mn);
tree[id].mx=max(tree[lid].mx,tree[rid].mx);
return;
}
int querymn(int id,int l,int r,int q,int w){
if(!id){
return tree[id].mn;
}
if(q<=l&&r<=w){
return tree[id].mn;
}
if(w<=mid){
return querymn(lid,l,mid,q,w);
}
else if(q>mid){
return querymn(rid,mid+1,r,q,w);
}
else{
return min(querymn(lid,l,mid,q,w),querymn(rid,mid+1,r,q,w));
}
}
int querymx(int id,int l,int r,int q,int w){
if(!id){
return tree[id].mx;
}
if(q<=l&&r<=w){
return tree[id].mx;
}
if(w<=mid){
return querymx(lid,l,mid,q,w);
}
else if(q>mid){
return querymx(rid,mid+1,r,q,w);
}
else{
return max(querymx(lid,l,mid,q,w),querymx(rid,mid+1,r,q,w));
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].x>>a[i].v;
}
for(int i=0;i<=(n<<5);i++){
tree[i].mn=1e9;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
add(rt,1,1e9,a[i].v,i);
l[i]=querymn(rt,1,1e9,a[i].v,1e9);
}
rt=0;
for(int i=1;i<=idd;i++){
tree[i].ls=0;
tree[i].rs=0;
tree[i].mx=0;
tree[i].mn=0;
}
for(int i=0;i<=(n<<5);i++){
tree[i].mn=1e9;
}
for(int i=n;i>=1;i--){
add(rt,1,1e9,a[i].v,i);
r[i]=querymx(rt,1,1e9,1,a[i].v);
}
rt=0;
for(int i=1;i<=idd;i++){
tree[i].ls=0;
tree[i].rs=0;
tree[i].mx=0;
tree[i].mn=0;
}
for(int i=1;i<=n;i++){
tu[r[i]].push_back(l[i]);
}
dp[0]=1;
sum[0]=1;
for(int i=1;i<=n;i++){
dp[i]=(sum[i-1]-sum[xing]+dp[xing]+modd)%modd;
sum[i]=(sum[i-1]+dp[i])%modd;
for(int j=0;j<tu[i].size();j++){
xing=max(xing,tu[i][j]);
}
}
cout<<(sum[n]-sum[xing]+dp[xing]+modd)%modd;
return 0;
}
浙公网安备 33010602011771号