【bzoj4070】[Apio2015]雅加达的摩天楼 分块+最短路

O(3*n*sqrt(n)+2*num*sqrt(n)+(m-num))

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 30010
#define N 15000010
#define inf 1000000000

using namespace std;

bool vis[110*maxn];
int pos[110][maxn],q[110*maxn];
int n,m,num,block,cnt,s,t;

void addedge(int x,int y,int z)
{
}

void spfa()
{
for (int i=0;i<=cnt;i++) dis[i]=inf;
int l=0,r=1;
q[1]=s;vis[s]=1;dis[s]=0;
while (l!=r)
{
l++;if (l==110*maxn) l=0;
int x=q[l];
if (dis[x]+len[p]<dis[to[p]])
{
dis[to[p]]=dis[x]+len[p];
if (!vis[to[p]])
{
r++;if (r==110*maxn) r=0;
vis[to[p]]=1;q[r]=to[p];
}
}
vis[x]=0;
}
}

int main()
{
scanf("%d%d",&n,&m);
cnt=n-1;block=min((int)sqrt(n),100);
for (int i=1;i<=block;i++)
for (int j=0;j<i;j++)
for (int k=j;k<n;k+=i)
{
pos[i][k]=++cnt;
}
for (int i=1;i<=m;i++)
{
int B,p;
scanf("%d%d",&B,&p);
if (i==1) s=B;
if (i==2) t=B;
else
{
for (int j=1;B+j*p<n;j++) addedge(B,B+j*p,j);
for (int j=1;B-j*p>=0;j++) addedge(B,B-j*p,j);
}
}
spfa();
if (dis[t]!=inf) printf("%d\n",dis[t]); else printf("-1\n");
return 0;
}