Привет, я пытаюсь реализовать дерево 2D-диапазона для rmq-ing, вот мой код, я думаю, что он недостаточно эффективен, есть ли что-то, что я могу сделать для оптимизации.
ls содержит список y, отсортированный на каждом узле
рт содержит дерево сегментов
p.fi.fi содержит координату x
p.fi.se содержит координату y
p.se содержит идентификатор точки
loc содержит узел x и узел y для каждого идентификатора
vector<pii> ls[400005];
vector<int> rt[400005];
pair<pii,int> p[100005];
vector<pii> loc[100005];
inline void merge(int id,vector<pii> &res,vector<pii> &a,vector<pii> &b)
{
int la = 0;
int lb = 0;
int sa = SIZE(a);
int sb = SIZE(b);
while(la < sa || lb < sb)
{
if (la >= sa) {res.pb(b[lb]);loc[b[lb].se].pb(mp(id,SIZE(res)-1));lb++;}
else if (lb >= sb) {res.pb(a[la]);loc[a[la].se].pb(mp(id,SIZE(res)-1));la++;}
else
{
if (a[la] < b[lb]) {res.pb(a[la]);loc[a[la].se].pb(mp(id,SIZE(res)-1));la++;}
else {res.pb(b[lb]);loc[b[lb].se].pb(mp(id,SIZE(res)-1));lb++;}
}
}
}inline void build_x(int n,int l,int r)
{
if (l == r)
{
ls[n].clear();
ls[n].pb(mp(p[l].fi.se,p[l].se));
rt[n].assign(SIZE(ls[n])<<2,0);
loc[p[l].se].pb(mp(n,0));
return;
}
int m = (l+r)>>1;
build_x((n<<1),l,m);
build_x((n<<1)+1,m+1,r);
ls[n].clear();
merge(n,ls[n],ls[(n<<1)],ls[(n<<1)+1]);
rt[n].assign(SIZE(ls[n])<<2,0);
}
inline int query_y(int nx,int n,int l,int r,int ly,int ry)
{
if (ly > ls[nx][r].fi || ry < ls[nx][l].fi) return 0;
if (ly <= ls[nx][l].fi && ls[nx][r].fi <= ry)
{
return rt[nx][n];
}
int res = 0;
int m = (l+r)>>1;
if (ly <= ls[nx][m].fi) MAX(res,query_y(nx,(n<<1),l,m,ly,min(ls[nx][m].fi,ry)));
if (ls[nx][m+1].fi <= ry) MAX(res,query_y(nx,(n<<1)+1,m+1,r,max(ls[nx][m+1].fi,ly),ry));
return res;
}inline int query_x(int n,int l,int r,int lx,int rx,int ly,int ry)
{
if (lx > p[r].fi.fi || rx < p[l].fi.fi) return 0;
if (lx <= p[l].fi.fi && p[r].fi.fi <= rx)
{
return query_y(n,1,0,SIZE(ls[n])-1,ly,ry);
}
int res = 0;
int m = (l+r)>>1;
if (lx <= p[m].fi.fi) MAX(res,query_x((n<<1),l,m,lx,min(p[m].fi.fi,rx),ly,ry));
if (p[m+1].fi.fi <= rx) MAX(res,query_x((n<<1)+1,m+1,r,max(p[m+1].fi.fi,lx),rx,ly,ry));
return res;
}
int nx;
inline void update_y(int n,int l,int r,int fy,int v)
{
if (l == r)
{
MAX(rt[nx][n],v);
return;
}
int m = (l+r)>>1;
if (fy <= m) update_y((n<<1),l,m,fy,v);
else update_y((n<<1)+1,m+1,r,fy,v);
rt[nx][n] = max(rt[nx][(n<<1)],rt[nx][(n<<1)+1]);
}
извините, если код был беспорядок, так как это моя первая реализация дерева диапазонов
Моя текущая реализация работает около 4 с, но мне нужно, чтобы она работала менее 3 с, вот мой полный реализация
Спасибо 🙂
Задача ещё не решена.
Других решений пока нет …