这题usaco上过了,但洛谷上不开O2就 t 了10个点。。。
用 umap 开 o2 才勉强苟过去,然后看别人用 map 轻轻松松100ms。。。
问下哪里可以卡常啊,这个做法没搞错的话应该是 O(plogp) 的吧,结果跑得比两个 log 还慢
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>
#include <fstream>
#include <unordered_map>
using namespace std;
const int MAXN = 2e5+5;
void setIO(string name) {
freopen((name+".in").c_str(),"r",stdin);
freopen((name+".out").c_str(),"w",stdout);
ios_base::sync_with_stdio(0);
}
vector<int> x_pos,y_pos;
int xx1,x2,yy1,y2,n,p,cntx,cnty,tot,dp[MAXN],dis[MAXN],ans,t = MAXN;
unordered_map<int,int> mpx,mpy;
struct Point{
int x,y,type,id;
bool operator < (const Point &oth) const{
return mpx[x]<mpx[oth.x] || (mpx[x]==mpx[oth.x] && mpy[y]<mpy[oth.y]);
}
}pt[MAXN<<2];
inline void add(int x, int y, int type, int id){
pt[++tot].x = x;
pt[tot].y = y;
pt[tot].id = id;
pt[tot].type = type;
}
inline int max(int a, int b){return a>b?a:b;}
namespace Segtree{
inline int read(){
register int a=0,f=1;register char c;
while((c=getchar())<'0')if(c=='-')f=-1;;
while(c>='0')a=a*10+(c^48),c=getchar();
return a*f;
}
#define lson (way<<1)
#define rson (way<<1|1)
#define mid (l+r)/2
int pos[MAXN],seg[MAXN<<2],lz[MAXN<<2];
inline void update(int way, int l, int r, int qlow, int val){
if (r==l && r==qlow) {seg[way] = max(seg[way],val);return;}
if (mid>=qlow)update(lson,l,mid,qlow,val);
else update(rson,mid+1,r,qlow,val);
seg[way] = max(seg[lson],seg[rson]);
}
inline long long query(int way, int l, int r, int qlow,int qhigh){
if (qlow<=l && r<=qhigh) return seg[way];
if (l>qhigh || r<qlow) return 0;
return max(query(lson,l,mid,qlow,qhigh),query(rson,mid+1,r,qlow,qhigh));
}
inline void solve();
};
inline void Segtree::solve(){
n = read(); p = read();
for (int i=1;i<=p;i++){
xx1 = read(); yy1 = read(); x2 = read(); y2 = read();
x_pos.push_back(xx1),x_pos.push_back(x2);
y_pos.push_back(yy1),y_pos.push_back(y2);
add(xx1,yy1,0,i);
add(x2,y2,1,i);
dis[i] = x2-xx1+y2-yy1;
}
sort(x_pos.begin(),x_pos.end());
sort(y_pos.begin(),y_pos.end());
x_pos.resize(distance(x_pos.begin(),unique(x_pos.begin(), x_pos.end())));
y_pos.resize(distance(y_pos.begin(),unique(y_pos.begin(), y_pos.end())));
for (int i=1;i<=x_pos.size();i++)mpx[x_pos[i-1]] = i;
for (int i=1;i<=y_pos.size();i++)mpy[y_pos[i-1]] = i;
sort(pt+1,pt+tot+1);
for (int i=1;i<=tot;i++){
int id = pt[i].id, type = pt[i].type, x = mpx[pt[i].x], y = mpy[pt[i].y];
if (!type){
dp[id] = query(1,1,t,1,y) + dis[id];
ans = max(ans,dp[id]);
}else{
update(1,1,t,y,dp[id]);
}
}
cout<< n*2-ans;
}
signed main(){
// setIO("boards");
Segtree::solve();
}
/*
10 5
5 2 6 3
4 5 9 6
9 1 9 4
4 6 4 7
1 5 2 6
*/