人傻常数大
查看原帖
人傻常数大
219099
pocafup楼主2020/7/9 08:39

这题usaco上过了,但洛谷上不开O2就 t 了10个点。。。

用 umap 开 o2 才勉强苟过去,然后看别人用 map 轻轻松松100ms。。。

问下哪里可以卡常啊,这个做法没搞错的话应该是 O(plogp)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
*/
2020/7/9 08:39
加载中...