菜鸡永远都在做着变聚的梦。

题意

  有 \(4\) 个点连成一个环,连接顺序依次为 \(1-2-3-4-1\)。相邻两个点之间有个距离 \(d_{i,i+1}\)(特别地,当 \(i=4\) 时为 \(d_{4,1}\))。

  有一个人在 \(2\) 号点,他要完成距离为 \(K\) 的跑步任务并回到 \(2\) 号点,问至少需要跑多长距离。

  \(1\le d_i\le 30000,\space 1\le K\le 10^{18}\)

题解

  剩余系裸题?墨墨的等式练习题?

  考场上瞎写了一波就交了,考后发现转移情况想 sb 了炸成 \(70\) 分了……(啪)

  

  首先你需要会解决这么一个经典问题:给你 \(n(n\le 20)\) 个数 \(a_1,a_2,...,a_n\),求用这些数能加出来的 \(\ge K(K\le 10^{18})\) 的最小值(每个数可以用任意多次),即求 \(a_1 x_1 + a_2 x_2 + ... + a_n x_n\) 在 \([K,\infty)\) 范围内的最小值。

  这就要用到一个东西:剩余系(我也忘了到底叫啥了,也可能是同余系)

  虽然 \(K\) 的范围很大,但注意到 \(a_i\) 的范围并不大,所以我们任取一个数 \(a_p\)(这里为了方便设 \(p\) 为 \(n\)),以此为模数建系。

  或者说,将 \([0,\infty]\) 内的正整数按照模 \(a_p\) 的值分类,所有模 \(a_n\) 的值相同的分入一类。显然我们只需要求出同一类数中最小的能加出来的数(设其为 \(Min\)),因为在这一类中,大于等于 \(Min\) 的所有数显然都能加出来(把 \(Min\) 加上若干个 \(a_n\) 即可),所以并不用考虑它们能不能被其它 \(a_i\) 加出来。

  那怎么求每一类中最小的能加出来的数呢?

  把 \([0,a_p-1]\) 中的每个正整数视为一个点,每个点有 \(n-1\) 条出边,\(i\) 号点的第 \(j\) 条出边指向 \((i+a_j)\% a_n\) 号点,边权为 \(a_j\),然后从 \(0\) 号点出发跑单源最短路即可。

  首先时间复杂度肯定是对的,点数为 \(a_n\),边数为 \(a_n\times (n-1)\),跑 \(\text{dij}\) 复杂度稳定 \(O(a_n\log a_n)\)。

  然后考虑正确性。因为边权是 \(a_i\),所以到 \(x\) 号点的最短路就是 模 \(K\) 得 \(x\) 的一类中 最小的一个能被一堆 \(a_i\) 加出来的数。这种做法用最短路算法保证了时间复杂度的正确性……好神仙啊……

  

  然后考虑本题。我们只需要随便选取一个大小合适的数 作为剩余系的模数就行了。

  不难发现 \(w=d_{1,2}\) 就很合适,\(2w\) 代表从 \(2\) 号点跑到 \(1\) 号点再跑回来。

  可以直接以 \(d_{1,2}\) 为模数建剩余系,那么设 \(dis_{i,j}\) 表示从起点出发到达 \(i\) 号点,距离模 \(2w\) 为 \(j\) 时的最短路。

  \(8w\) 个状态跑 \(\text{dij}\),复杂度 \(O(w\log w)\)。

  我 tm 忘了剩余系的模数可以取最小值,之前一直在取最大值

#include<bits/stdc++.h>
#define ll long long
#define N 100010
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
const ll ll_inf = 9223372036854775807ll >> 1;
using namespace std;
inline ll read(){
ll x=0; bool f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
if(f) return x; return 0-x;
}
ll k;
int w,d[5];
ll dis[5][N];
bool vis[5][N];
priority_queue<pair<ll,pii>, vector<pair<ll,pii> >, greater<pair<ll,pii> > > Q;
void Dij(){
for(int i=0; i<4; ++i)
for(int j=0; j<w; ++j)
dis[i][j]=ll_inf, vis[i][j]=0;
dis[1][0]=0;
Q.push(mp(0,mp(1,0)));
pii tmp; int x,y;
while(!Q.empty()){
//int faq=Q.top().fi;
tmp=Q.top().se; Q.pop();
x=tmp.fi, y=tmp.se;
if(vis[x][y]) continue;
//cout<<faq<<' '<<x<<' '<<y<<endl;
vis[x][y]=1;
int x1=(x+1)%4, x2=(x+3)%4;
int y1=(y+d[x])%w, y2=(y+d[x2])%w;
if(dis[x1][y1]>dis[x][y]+d[x]){
dis[x1][y1]=dis[x][y]+d[x];
Q.push(mp(dis[x1][y1],mp(x1,y1)));
}
if(dis[x2][y2]>dis[x][y]+d[x2]){
dis[x2][y2]=dis[x][y]+d[x2];
Q.push(mp(dis[x2][y2],mp(x2,y2)));
}
}
}
int main(){
int T=read();
while(T--){
k=read();
for(int i=0; i<4; ++i) d[i]=read();
w=min(d[0]<<1,d[1]<<1);
Dij();
//cout<<dis[1][2165%1200]<<endl;
while(dis[1][k%w]>k) ++k;
printf("%lld\n",k);
}
return 0;
}

  scb 神仙推出了个不同的做法(但还是以剩余系为基础),需要对 \(4\) 个式子各求一遍经典问题,但是跑得很快 Orz 大家有兴趣可以去学(mo)一下

【hdu 6071】Lazy Running的更多相关文章

  1. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  2. 【HDU 5647】DZY Loves Connecting(树DP)

    pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...

  3. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  4. 【HDU 2196】 Computer(树的直径)

    [HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...

  5. 【HDU 2196】 Computer (树形DP)

    [HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...

  6. 【HDU 5145】 NPY and girls(组合+莫队)

    pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...

  7. 【hdu 1043】Eight

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...

  8. 【HDU 3068】 最长回文

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3068 [算法] Manacher算法求最长回文子串 [代码] #include<bits/s ...

  9. 【HDU 4699】 Editor

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4699 [算法] 维护两个栈,一个栈放光标之前的数,另外一个放光标之后的数 在维护栈的同时求最大前缀 ...

随机推荐

  1. 重启 hdfs and yarn datanode

    1- start-all.sh and stop-all.sh: Used to start and stop hadoop daemons all at once. Issuing it on th ...

  2. 【Linux】【二】linux 压缩文件(txt)、查看压缩文件内容、解压缩文件、

    通过Xshell 压缩文件.解压缩文件 gzip tools.txt 压缩[tools.txt]文件 zcat tools.txt.gz   查看压缩文件[tools.txt.gz]内容 gunzip ...

  3. Kubernetes中的PV和PVC

    K8S引入了一组叫作Persistent Volume Claim(PVC)和Persistent Volume(PV)的API对象,大大降低了用户声明和使用持久化Volume的门槛.在Pod的Vol ...

  4. web开发常识

    web开发基本常识 服务器(硬件) 维基百科定义: 服务器作为硬件来说,通常是指那些具有较高计算能力,能够提供给多个用户使用的计算机.服务器与PC机的不同点很多,例如PC机在一个时刻通常只为一个用户服 ...

  5. 分布式架构-Redis 从入门到精通 完整案例 附源码

    导读 篇幅较长,干货十足,阅读需要花点时间,全部手打出来的字,难免出现错别字,敬请谅解.珍惜原创,转载请注明出处,谢谢~! NoSql介绍与Redis介绍 什么是Redis? Redis是用C语言开发 ...

  6. 史上最简单的CentOS7破解密码方法,有图有真相

    #############破解CentOS7密码详细过程 一.开机重启,按任意键停住,有时没停住,是鼠标键未在服务器中,点一下就好     二.按e键进入单用户模式     三.在UTF-8后面加上i ...

  7. 【LeetCode】 454、四数之和 II

    题目等级:4Sum II(Medium) 题目描述: Given four lists A, B, C, D of integer values, compute how many tuples (i ...

  8. 浅谈TCP扫描与SYN扫描与FIN扫描

    下面就这三种方法来小小的探讨一下,不对的地方还请多多指教! 1:TCP扫描 相对来说是速度比较慢的一种,为什么会慢呢?因为这种方法在扫描的时候会从本地主机的一个端口向目标主机的一个端口发出一个连接请求 ...

  9. JS中FireFox新开窗口预览打印处理的方式

    仅提供思路,勿喷如下↓ /** * 打印方法 * @param dom 要被打印的dom元素 * @param parentClassName 该组件的页面根组件class名 * @param pag ...

  10. python 爬虫 urllib模块 发起post请求

    urllib模块发起的POST请求 案例:爬取百度翻译的翻译结果 1.通过浏览器捉包工具,找到POST请求的url 针对ajax页面请求的所对应url获取,需要用到浏览器的捉包工具.查看百度翻译针对某 ...