BDF1 @ 2017-02-09 11:55:34
···cpp
#include<ext/pb_ds/priority_queue.hpp>
#include<cstdio>
#include<cstring>
using namespace std;
struct lzqhkf{
int x,y;long long w;
lzqhkf(int a,int b,long long d):x(a),y(b),w(d){};
lzqhkf(){x=y=w=0;}
bool operator<(lzqhkf hkf)const{
return w>hkf.w;
}
};
struct clc{
int x,y,X,Y,id;
};
clc A[102400],B[102400];
typedef __gnu_pbds::priority_queue<lzqhkf>heap;
heap a;
bool*in[100007];
heap::point_iterator*id[100007];
int T[4]={-1,1,0,0},Z[4]={0,0,-1,1},n,m,x,y,xx,yy,Q;
int*dis[100007];int ans[100007];
int*c[4][100007];
void di(int x_,int y_,int x,int X,int y,int Y){
a.clear();
for(int i=x-1;i<=X+1;i++)for(int j=y-1;j<=Y+1;j++)dis[i][j]=1073741823,in[i][j]=0;
in[x_][y_]=1;dis[x_][y_]=0;
id[x_][y_]=a.push(lzqhkf(x_,y_,0));
while(!a.empty()){
lzqhkf st=a.top();a.pop();
int _x=st.x,_y=st.y;int w=st.w;
//printf("now %d %d\n",_x,_y);
for(int k=0;k<4;k++){
int xx=_x+T[k],yy=_y+Z[k];
//printf("xx=%d yy=%d x=%d y=%d X=%d Y=%d\n",xx,yy,x,y,X,Y);
if(xx<x||xx>X||yy<y||yy>Y)continue;
if(w+c[k][_x][_y]<dis[xx][yy]){
dis[xx][yy]=w+c[k][_x][_y];
//printf("%d %d %d\n",xx,yy,dis[xx][yy]);
if(in[xx][yy])a.modify(id[xx][yy],lzqhkf(xx,yy,dis[xx][yy]));
else in[xx][yy]=1,id[xx][yy]=a.push(lzqhkf(xx,yy,dis[xx][yy]));
}//else printf("%d %d:%d\n",w,c[k][x][y],dis[xx][yy]);
}
}
}
void sol(int x,int X,int y,int Y,int q,int Q){
if(q>Q)return;
if(X-x>Y-y){
int m=x+X>>1;
for(int i=y;i<=Y;i++){
di(m,i,x,X,y,Y);
//printf("(%d %d) (%d %d) (%d %d)\n",x,y,X,Y,m,i);
//for(int i=x;i<=X;i++,puts(""))for(int j=y;j<=Y;j++)printf("%d ",dis[i][j]);
for(int j=q;j<=Q;j++)if(ans[A[j].id]>dis[A[j].x][A[j].y]+dis[A[j].X][A[j].Y])
ans[A[j].id]=dis[A[j].x][A[j].y]+dis[A[j].X][A[j].Y];
}
int j=q,k=Q;
for(int i=q;i<=Q;i++)if(A[i].x<m&&A[i].X<m)B[j++]=A[i];
else if(A[i].x>m&&A[i].X>m)B[k--]=A[i];
for(int i=q;i<j;i++)A[i]=B[i];for(int i=Q;i>k;i--)A[i]=B[i];
sol(x,m-1,y,Y,q,j-1),sol(m+1,X,y,Y,k+1,Q);
}
else{
int m=y+Y>>1;
for(int i=x;i<=X;i++){
di(i,m,x,X,y,Y);
//printf("(%d %d) (%d %d) (%d %d)\n",x,y,X,Y,i,m);
//for(int i=x;i<=X;i++,puts(""))for(int j=y;j<=Y;j++)printf("%d ",dis[i][j]);
for(int j=q;j<=Q;j++)if(ans[A[j].id]>dis[A[j].x][A[j].y]+dis[A[j].X][A[j].Y])
ans[A[j].id]=dis[A[j].x][A[j].y]+dis[A[j].X][A[j].Y];
}
int j=q,k=Q;
for(int i=q;i<=Q;i++)if(A[i].y<m&&A[i].Y<m)B[j++]=A[i];
else if(A[i].y>m&&A[i].Y>m)B[k--]=A[i];
for(int i=q;i<j;i++)A[i]=B[i];for(int i=Q;i>k;i--)A[i]=B[i];
sol(x,X,y,m-1,q,j-1),sol(x,X,m+1,Y,k+1,Q);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int I=0;I<4;I++)for(int i=0;i<=n+1;i++)c[I][i]=new int[m+2];
for(int i=0;i<=n+1;i++)dis[i]=new int[m+2],in[i]=new bool[m+2],id[i]=new heap::point_iterator[m+2];
for(int i=1;i<=n;i++)for(int j=1;j<m;j++)scanf("%d",&c[3][i][j]),c[2][i][j+1]=c[3][i][j];
for(int i=1;i<n;i++)for(int j=1;j<=m;j++)scanf("%d",&c[1][i][j]),c[0][i+1][j]=c[1][i][j];
scanf("%d",&Q);
//for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)printf("(%d %d %d %d\n)")
for(int i=1;i<=Q;i++){
int x,y,X,Y;scanf("%d%d%d%d",&x,&y,&X,&Y);
A[i]=(clc){x,y,X,Y,i};ans[i]=1e9+7;
}sol(1,n,1,m,1,Q);
for(int i=1;i<=Q;i++)printf("%d\n",ans[i]);
}
···
by kkksc03 @ 2017-02-11 02:48:19
@BDF1 已经加大时限
by system_has_collapsed @ 2018-02-09 16:52:39
#include<bits/stdc++.h>
template<typename T> inline void read(T& a)
{
T x = 0,f = 1;
char ch = getchar();
while((ch < '0') or (ch > '9'))
{
if(ch == '-' )
f = -1;
ch = getchar();
}
while((ch >= '0') and (ch <= '9'))
{
x = x * 10 + ch - '0';
ch = getchar();
}
a = x * f;
}
using namespace std;
inline void readl()
{
char ch;
ch = getchar();
while(ch != '\n')
ch = getchar();
}
int dis[200005],dis2[200005],tp[200005],f[200005],v[200005],i,j,k,n,m,cnt,w[100005];
int r[200005],c[200005],q[100005][5],a[100005],qq,ans[100005];
const int fx[4] = {-1,0,1,0};
const int fy[4] = {0,-1,0,1};
inline void up(int x)
{
int t,i;
while(x > 1)
{
i = x / 2;
if(dis[tp[x]] < dis[tp[i]])
{
swap(tp[i],tp[x]);
w[tp[x]] = x;
w[tp[i]] = i;
x = i;
}
else
break;
}
}
inline void down(int x)
{
int t,i,j;
while (true)
{
i = x * 2;
j = i + 1;
if((j <= cnt) and (dis[tp[j]] < dis[tp[i]]))
i = j;
if((i <= cnt) and (dis[tp[i]] < dis[tp[x]]))
{
swap(tp[x],tp[i]);
w[tp[x]] = x;
w[tp[i]] = i;
x = i;
}
else
break;
}
}
inline void dij(int x,int y,int ll1,int rr1,int ll2,int rr2)
{
cnt = 0;
int k,xx,yy,xxx,yyy,disk,mu,jia,tot = 0;
int i,j;
for(i = ll1;i <= rr1;i++)
for(j = ll2;j <= rr2;j++)
{
tot++;
mu = m * (i - 1) + j - 1;
v[mu] = 0;
if((i == x) and (j == y))
dis[mu] = 0,cnt++,tp[cnt] = mu,w[mu] = cnt,up(cnt);
else
dis[mu] = 1000000000;
}
for(i = 1;i <= tot;i++)
{
k = tp[1];
v[k] = 1;
disk = dis[k];
dis2[k] = dis[k];
dis[k] = 2000000000;
down(1);
xx = k / m + 1;
yy = k % m + 1;
for(j = 0;j <= 3;j++)
if((xx + fx[j] >= ll1) and (xx + fx[j] <= rr1) and (yy + fy[j] >= ll2) and (yy + fy[j] <= rr2))
{
xxx = xx + fx[j];
yyy = yy +fy[j];
mu = m *(xxx - 1) + yyy - 1;
if(v[mu] == 1)
continue;
if(j == 0)
jia = c[mu];
else if (j == 1)
jia=r[mu];
else
if(j == 2)
jia = c[mu - m];
else
jia = r[mu - 1];
if(disk + jia < dis[mu])
{
if(dis[mu] == 1000000000)
cnt++,tp[cnt] = mu,w[mu] = cnt;
dis[mu] = disk + jia;
up(w[mu]);
}
}
}
}
inline bool in(int x,int l1,int r1,int l2,int r2)
{
return ((q[x][1] >= l1) and (q[x][1] <= r1) and (q[x][2] >= l2) and (q[x][2] <= r2) and (q[x][3] >= l1) and (q[x][3] <= r1) and (q[x][4] >= l2) and (q[x][4] <= r2));
}
void ss(int l1,int r1,int l2,int r2,int ql,int qr)
{
if((l1 > r1) or (l2 > r2) or (ql > qr))
return;
int i = ql,j = qr,l3 = l1,r3 = r1,l4 = l2,r4 = r2,l5 = l1,r5 = r1,l6 = l2,r6 = r2,x,midx,t,ii,jj;
if((r2 - l2 > r1 - l1))
{
x = 2;
midx = (r2 + l2) / 2;
r4 = midx - 1;
l6 = midx + 1;
}
else
{
x = 1;
midx = (r1 + l1) / 2;
r3 = midx - 1;
l5 = midx + 1;
}
while(i <= j)
{
while((i <= qr) and ((in(a[i],l3,r3,l4,r4)) or (in(a[i],l5,r5,l6,r6))))
i++;
while((j >= ql) and (not ((in(a[j],l3,r3,l4,r4)) or (in(a[j],l5,r5,l6,r6)))))
j--;
if (i <= j)
{
swap(a[i],a[j]);
i++;
j--;
}
}
if(x == 1)
{
for(ii = l2;ii <= r2;ii++)
{
dij(midx,ii,l1,r1,l2,r2);
for(jj = ql;jj <= qr;jj++)
ans[a[jj]] = min(ans[a[jj]],dis2[m * (q[a[jj]][1] - 1) + q[a[jj]][2] - 1] + dis2[m * (q[a[jj]][3] - 1) + q[a[jj]][4] - 1]);
}
}
else
{
for(ii = l1;ii <= r1;ii++)
{
dij(ii,midx,l1,r1,l2,r2);
for(jj = ql;jj <= qr;jj++)
ans[a[jj]] = min(ans[a[jj]],dis2[m * (q[a[jj]][1] - 1) + q[a[jj]][2] - 1] + dis2[m * (q[a[jj]][3] - 1) + q[a[jj]][4] - 1]);
}
}
qr = i - 1;
if(ql > qr)
return;
i = ql;
j = qr;
while(i <= j)
{
while((i <= qr) and (in(a[i],l3,r3,l4,r4)))
i++;
while((j >= ql) and (in(a[j],l5,r5,l6,r6)))
j--;
if(i <= j)
{
swap(a[i],a[j]);
i++;
j--;
}
}
if(i <= qr)
ss(l5,r5,l6,r6,i,qr);
if(j <= ql)
ss(l3,r3,l4,r4,ql,j);
}
int main()
{
cin >> n;
cin >> m;
for(i = 1;i <= n;i++)
for(j = 1;j <= m - 1;j++)
cin >> r[m * (i - 1) + j - 1];
for(i = 1;i <= n - 1;i++)
for(j = 1;j <= m;j++)
cin >> c[m * (i - 1) + j - 1];
cin >> qq;
for(i = 1;i <= qq;i++)
{
cin >> q[i][1];
cin >> q[i][2];
cin >> q[i][3];
cin >> q[i][4];
a[i] = i;
ans[i] = 2000000000;
}
ss(1,n,1,m,1,qq);
for(i = 1;i <= qq;i++)
cout << ans[i] << endl;//printf("%d\n",ans[i]);
}
麻烦看一下有什么错误