2090. 「ZJOI2016」旅行者

链接

loj

思路

\((l,mid)(mid+1,r)\).考虑跨过mid的贡献。

假设选的中间那条线的点为gzy,贡献为\(dis(x,gzy)+dis(gzy,y)\)

那就计算n遍最短路,一次分治为\(n^2mlog{nm}\)

设S=n*m.矩阵的长度是不定的,每次取最长的边进行分治是最好的,n最坏为\(\sqrt{n}\)。

\(f(n)=2*f(\frac{n}{2})+S\sqrt{S}logS。所以总的复杂度就是\)\(S\sqrt{S}logS\)

都在同侧的也需要跨一跨

代码

#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int _=1e5+7,INF=0x3f3f3f3f;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,m,q,ans[_],vis[_];
struct node {
int x,y,X,Y,u,v,id;
}Q[_],tmp[_];
bool cmp(node a,node b) {return a.id<b.id;}
struct edge {int v,nxt,q;}e[_];
int head[_],tot;
void add(int u,int v,int q) {
e[++tot].v=v;
e[tot].q=q;
e[tot].nxt=head[u];
head[u]=tot;
}
int id(int x,int y) {return (x-1)*m+y;}
struct T_T {
int u,val;
T_T(int a=0,int b=0) {u=a,val=b;}
bool operator < (const T_T &b) const {return val>b.val;}
};
int dis[_];
void dij(int S) {
dis[S]=0;
priority_queue<T_T> q;
q.push(T_T(S,0));
while(!q.empty()) {
T_T u=q.top();q.pop();
if(dis[u.u]!=u.val) continue;
for(int i=head[u.u];i;i=e[i].nxt) {
int v=e[i].v;
if(vis[v]&&dis[v]>u.val+e[i].q) {
dis[v]=u.val+e[i].q;
q.push(T_T(v,dis[v]));
}
}
}
}
void solve(int x,int y,int X,int Y,int l,int r) {
if(l>r) return;
if(x==X&&y==Y) {
for(int i=l;i<=r;++i) ans[Q[i].id]=0;
return;
}
if(Y-y>X-x) {
int mid=(Y+y)>>1;
FOR(i,x,X) {
FOR(j,x,X) FOR(k,y,Y) dis[id(j,k)]=INF;
dij(id(i,mid));
FOR(j,l,r)
ans[Q[j].id]=min(dis[Q[j].u]+dis[Q[j].v],ans[Q[j].id]);
}
FOR(i,x,X) vis[id(i,mid)]=0;
int p=l,q=r;
FOR(i,l,r) {
if(max(Q[i].y,Q[i].Y)<=mid) tmp[p++]=Q[i];
if(min(Q[i].y,Q[i].Y)>mid) tmp[q--]=Q[i];
}
FOR(i,l,r) Q[i]=tmp[i];
solve(x,y,X,mid,l,p-1);
solve(x,mid+1,X,Y,q+1,r);
} else {
int mid=(X+x)>>1;
FOR(i,y,Y) {
FOR(j,x,X) FOR(k,y,Y) dis[id(j,k)]=INF;
dij(id(mid,i));
FOR(j,l,r)
ans[Q[j].id]=min(dis[Q[j].u]+dis[Q[j].v],ans[Q[j].id]);
}
FOR(i,y,Y) vis[id(mid,i)]=0;
int p=l,q=r;
FOR(i,l,r) {
if(max(Q[i].x,Q[i].X)<=mid) tmp[p++]=Q[i];
if(min(Q[i].x,Q[i].X)>mid) tmp[q--]=Q[i];
}
FOR(i,l,r) Q[i]=tmp[i];
solve(x,y,mid,Y,l,p-1);
solve(mid+1,y,X,Y,q+1,r);
}
}
int main() {
n=read(),m=read();
FOR(i,1,n) FOR(j,1,m-1) {
int val=read();
add(id(i,j),id(i,j+1),val);
add(id(i,j+1),id(i,j),val);
}
FOR(i,1,n-1) FOR(j,1,m) {
int val=read();
add(id(i,j),id(i+1,j),val);
add(id(i+1,j),id(i,j),val);
}
FOR(i,1,n) FOR(j,1,m) vis[id(i,j)]=1;
q=read();
FOR(i,1,q) {
Q[i].x=read(),Q[i].y=read(),
Q[i].u=id(Q[i].x,Q[i].y);
Q[i].X=read(),Q[i].Y=read(),
Q[i].v=id(Q[i].X,Q[i].Y);
Q[i].id=i,ans[i]=INF;
}
solve(1,1,n,m,1,q);
FOR(i,1,q) printf("%d\n",ans[i]);
return 0;
}

2090. 「ZJOI2016」旅行者 分治,最短路的更多相关文章

  1. @loj - 2090@ 「ZJOI2016」旅行者

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Y 来到了一个新的城市旅行.她发现了这个城市的布局是网格状的 ...

  2. 【LOJ】#2090. 「ZJOI2016」旅行者

    题解 每次按较长边把矩形分成两半,找一个中间轴,轴上的每个点跑一边最短路更新所有的答案 然后把矩形分成两半,递归下去 代码 #include <bits/stdc++.h> #define ...

  3. 「ZJOI2016」旅行者 解题报告

    「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...

  4. loj2090 「ZJOI2016」旅行者

    分治+最短路,很套路的 #include <algorithm> #include <iostream> #include <cstring> #include & ...

  5. 「ZJOI2016」解题报告

    「ZJOI2016」解题报告 我大浙的省选题真是超级神仙--这套已经算是比较可做的了. 「ZJOI2016」旅行者 神仙分治题. 对于一个矩形,每次我们从最长边切开,最短边不会超过 \(\sqrt{n ...

  6. 「ZJOI2016」大森林 解题报告

    「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...

  7. 「bzoj1003」「ZJOI2006」物流运输 最短路+区间dp

    「bzoj1003」「ZJOI2006」物流运输---------------------------------------------------------------------------- ...

  8. [BZOJ4456] [Zjoi2016]旅行者 分治+最短路

    4456: [Zjoi2016]旅行者 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 777  Solved: 439[Submit][Status] ...

  9. 【BZOJ4456】[Zjoi2016]旅行者 分治+最短路

    [BZOJ4456][Zjoi2016]旅行者 Description 小Y来到了一个新的城市旅行.她发现了这个城市的布局是网格状的,也就是有n条从东到西的道路和m条从南到北的道路,这些道路两两相交形 ...

随机推荐

  1. 异步IO与回调

    最好了解 Java NIO 中 Buffer.Channel 和 Selector 的基本操作,主要是一些接口操作,比较简单. 本文将介绍非阻塞 IO 和异步 IO,也就是大家耳熟能详的 NIO 和 ...

  2. Mysql插入text类型字段错误记录 com.mysql.jdbc.MysqlDataTruncation: Data truncation: #22001

    一次插入操作报如下错误 com.mysql.jdbc.MysqlDataTruncation: Data truncation: #22001 是说字段值长度超过限制. MySQL TEXT数据类型的 ...

  3. JavaScript:计算1在数字中出现的次数

    题目: 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量). 示例 1: 输入:00000000000000000000000000001011 输 ...

  4. 【LeetCode】145. Binary Tree Postorder Traversal

    Difficulty: Hard  More:[目录]LeetCode Java实现 Description https://leetcode.com/problems/binary-tree-pos ...

  5. java.lang.NoClassDefFoundError: javax/el/ELManager

    今天搭建一个ssm框架的项目,报了一个令我怀疑人生的错误: java.lang.NoClassDefFoundError: javax/el/ELManager 网上说出现这种错,大概有以下两个原因: ...

  6. WPF布局原则

    WPF系统使用基于流布局的布局标准,开发人员创建与显示分辨率和窗口大小无关的用户界面.在不同显示器上可以进行很好的缩放. 首先来谈一谈布局原则: WPF窗口只能包含一个元素(Window元素属于内容控 ...

  7. TransactionScope 使用的注意事项

    前两天为了给代码做一些事务封装,写了个小Demo,用TransactionScope代码块实现. 第一条更新成功后第二条刻意抛出异常,结果发现第一条总执行成功,这不符合预期,于是开始一步步跟踪调试. ...

  8. lift提升图

    Lift图衡量的是,与不利用模型相比,模型的预测能力“变好”了多少,lift(提升指数)越大,模型的运行效果越好. TP:划一个阈值后的正样本. P:总体的正样本. 在模型评估中,我们常用到增益/提升 ...

  9. java--Date时间

    Date: 表示特定的瞬间,精确到毫秒,通过方法设定自己所表示的时间,可以表示任意的时间 System.currentTimeMillis() :返回的当前系统时间, 1970-1-1 至今的毫秒数 ...

  10. 网页百度地图api,支持位置偏移

    网页百度地图api,支持位置偏移 需加载 jq <style type="text/css"> #allmap {width:100%; height:100%; bo ...