打模拟赛只会线段树优化建图,于是只有72分
后来问 ldx 神仙学长,他说是个叫四分树的东西,我一脸懵逼?
他说线段树是一分为2,四方树是把一个矩阵一分为4
我想了想,好有道理啊!于是开始自己 yy
考虑动态开点,把每个点插入到树中,类似线段树,只会多log个节点
但优化建边的时候,每条边会想树上连log^2 个点,显然要凉
于是我想,dijsktra的时候在矩阵里面直接查然后更新最短路就可以了,不需要记录边
另外四方树更线段树一样啊,自己瞎写一下居然对了,真是个毒瘤的数据结构 !
#include<bits/stdc++.h>
#define N 3000050
#define M 70050
using namespace std;
int read(){
int cnt = 0, f = 1; char ch = 0;
while(!isdigit(ch)){ ch = getchar(); if(ch == '-') f = -1;}
while(isdigit(ch)) cnt = (cnt << 1) + (cnt << 3) + (ch-'0'), ch = getchar();
return cnt * f;
}
typedef long long ll;
int n, m, W, H;
struct Node{ int p, t, L, R, D, U;};
vector<Node> v[M];
int rt, ch[N][4], res, pos[N], pre[N];
void Insert(int &u, int lx, int rx, int ly, int ry, int x, int y, int id){
if(!u) u = ++res;
if(lx == rx && ly == ry){ pos[id] = u; pre[u] = id; return; }
int midx = (lx + rx) >> 1, midy = (ly + ry) >> 1;
if(x <= midx){
if(y <= midy) Insert(ch[u][0], lx, midx, ly, midy, x, y, id);
else Insert(ch[u][1], lx, midx, midy+1, ry, x, y, id);
}
else{
if(y <= midy) Insert(ch[u][2], midx+1, rx, ly, midy, x, y, id);
else Insert(ch[u][3], midx+1, rx, midy+1, ry, x, y, id);
}
}
#define mp make_pair
ll dis[N]; bool vis[N];
priority_queue<pair<ll, int> > q;
void Modify(int u, int lx, int rx, int ly, int ry, ll d, Node v){
if(!u) return; if(dis[u] <= d + v.t) return;
if(v.L <= lx && rx <= v.R && v.D <= ly && ry <= v.U){
if(d + v.t < dis[u]){
dis[u] = d + v.t;
q.push(mp(-dis[u], u));
} return;
} int midx = (lx + rx) >> 1, midy = (ly + ry) >> 1;
if(ch[u][0] && v.L <= midx && v.D <= midy) Modify(ch[u][0], lx, midx, ly, midy, d, v);
if(ch[u][1] && v.L <= midx && v.U > midy) Modify(ch[u][1], lx, midx, midy+1, ry, d, v);
if(ch[u][2] && v.R > midx && v.D <= midy) Modify(ch[u][2], midx+1, rx, ly, midy, d, v);
if(ch[u][3] && v.R > midx && v.U > midy) Modify(ch[u][3], midx+1, rx, midy+1, ry, d, v);
}
int main(){
freopen("jump.in","r",stdin);
freopen("jump.out","w",stdout);
n = read(), m = read(), W = read(), H = read(); res = n;
for(int i=1; i<=n; i++){
int x = read(), y = read();
Insert(rt, 1, W, 1, H, x, y, i);
}
for(int i=1; i<=m; i++){
int p = read(), t = read(), L = read(), R = read(), D = read(), U = read();
v[p].push_back((Node){p, t, L, R, D, U});
}
memset(dis, 127, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[pos[1]] = 0; q.push(mp(0, pos[1]));
while(!q.empty()){
int x = q.top().second; q.pop();
if(vis[x]) continue; vis[x] = true;
if(pre[x]){
for(int i=0; i<v[pre[x]].size(); i++){
Node now = v[pre[x]][i];
Modify(rt, 1, W, 1, H, dis[x], now);
}
}
else{
for(int j = 0; j < 4; j++){
if(ch[x][j] && dis[ch[x][j]] > dis[x]){
dis[ch[x][j]] = dis[x]; q.push(mp(-dis[ch[x][j]], ch[x][j]));
}
}
}
}
for(int i=2; i<=n; i++) printf("%lld\n", dis[pos[i]]);
return 0;
}