只能过样例:(

P3350 [ZJOI2016] 旅行者

NOIer @ 2024-03-03 12:33:00

#include <bits/stdc++.h>
using namespace std;
#define se second
#define fr first
const int N = 2e5+1145,INF = 1e9;
typedef pair<int,int> PII;
int mp[N],n,m,q,ans[N];

inline int zf(int x,int y){return (x-1)*n+y; }
inline int dyx(int id){ return ((id-1)/n)+1; }
inline int dyy(int id){ return ((id-1)%n)+1; }
struct ASK{
    int x,y,xx,yy,id;
};
int first[N],idx;
struct edge{
    int ne,d,val;
}ed[N*2];
void add_edge(int e,int d,int val){
    idx++,ed[idx].d=d,ed[idx].val=val,ed[idx].ne=first[e],first[e]=idx;
}
int dist[N],vis[N];
void dijkstra(int s,int lx,int rx,int ly,int ry){
    priority_queue<PII,vector<PII>,greater<PII> > Q;
    for(int i=lx;i<=rx;i++) 
        for(int j=ly;j<=ry;j++) 
            dist[zf(i,j)]=INF,vis[zf(i,j)]=0;
    Q.push(make_pair(0,s));
    dist[s]=0;
    while(Q.size()){
        int t=Q.top().se;
        Q.pop();
        if(vis[t]) continue;
        vis[t]=1;
        for(int i=first[t];i;i=ed[i].ne){
            int d=ed[i].d;
            if(dist[d]>dist[t]+ed[i].val&&dyx(d)>=lx&&dyx(d)<=rx&&dyy(d)>=ly&&dyy(d)<=ry){
                dist[d]=dist[t]+ed[i].val;
                Q.push(make_pair(dist[d],d));
            }
        }
    }
}

void solve(int lx,int rx,int ly,int ry,vector<ASK> opt){

    if(!opt.size()) return ;
    if(lx==rx && ly==ry) {
        for(int i=0;i<opt.size();i++) ans[opt[i].id]=0;
        return ;
    } 
    if(rx-lx>=ry-ly){//横切 
        int mid=rx+lx>>1;
        for(int i=ly;i<=ry;i++){
            dijkstra(zf(mid,i),lx,rx,ly,ry);
            for(int j=0;j<opt.size();j++) {
                ans[opt[j].id]=min(ans[opt[j].id],dist[zf(opt[j].x,opt[j].y)]+dist[zf(opt[j].xx,opt[j].yy)]);
//              if(j==0) printf("%d %d %d %d QWQ %d %d %d\n ",lx,rx,ly,ry,i,dist[zf(opt[j].x,opt[j].y)],dist[zf(opt[j].xx,opt[j].yy)]);
            }
        }
        vector<ASK> L,R;
        for(int i=0;i<opt.size();i++) 
            if(max(opt[i].x,opt[i].xx)<=mid) L.push_back(opt[i]);
            else if(min(opt[i].x,opt[i].xx)>mid) R.push_back(opt[i]);
        solve(lx,mid,ly,ry,L),solve(mid+1,rx,ly,ry,R);
    }else{//纵切 
        int mid=ry+ly>>1;
        for(int i=lx;i<=rx;i++){
            dijkstra(zf(i,mid),lx,rx,ly,ry);
            for(int j=0;j<opt.size();j++) ans[opt[j].id]=min(ans[opt[j].id],dist[zf(opt[j].x,opt[j].y)]+dist[zf(opt[j].xx,opt[j].yy)]);
        }
        vector<ASK> L,R;
        for(int i=0;i<opt.size();i++) 
            if(max(opt[i].y,opt[i].yy)<=mid) L.push_back(opt[i]);
            else if(min(opt[i].y,opt[i].yy)>mid) R.push_back(opt[i]);
        solve(lx,rx,ly,mid,L),solve(lx,rx,mid+1,ry,R);
    }
}

int main()
{
    memset(ans,0x3f,sizeof ans);
    cin>>n>>m;
    for(int val,i=1;i<=n;i++) 
        for(int j=1;j<m;j++) 
            scanf("%d",&val),add_edge(zf(i,j),zf(i,j+1),val),add_edge(zf(i,j+1),zf(i,j),val);
    for(int val,i=1;i<n;i++) 
        for(int j=1;j<=m;j++) 
            scanf("%d",&val),add_edge(zf(i,j),zf(i+1,j),val),add_edge(zf(i+1,j),zf(i,j),val);
    vector<ASK> opt;
    cin>>q;
    for(int i=1;i<=q;i++) {
        int u,v,uu,vv;
        scanf("%d%d%d%d",&u,&v,&uu,&vv);
        opt.push_back({u,v,uu,vv,i});
    }
    solve(1,n,1,m,opt);
    for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
    return 0;
}

|