NOI2018 D1T1 [NOI2018]归程 解题报告
P4768 [NOI2018]归程
题目描述
本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定。
魔力之都可以抽象成一个 \(n\) 个节点、\(m\) 条边的无向连通图(节点的编号从 \(1\) 至 \(n\))。我们依次用 \(l,a\) 描述一条边的长度、海拔。
作为季风气候的代表城市,魔力之都时常有雨水相伴,因此道路积水总是不可避免的。由于整个城市的排水系统连通,因此有积水的边一定是海拔相对最低的一些边。我们用水位线来描述降雨的程度,它的意义是:所有海拔不超过水位线的边都是有积水的。
Yazid是一名来自魔力之都的OIer,刚参加完ION2018的他将踏上归程,回到他温暖的家。
Yazid 的家恰好在魔力之都的 \(1\) 号节点。对于接下来 \(Q\) 天,每一天Yazid 都会告诉你他的出发点 \(v\) ,以及当天的水位线\(p\)。 每一天,Yazid 在出发点都拥有一辆车。这辆车由于一些故障不能经过有积水的边。 Yazid 可以在任意节点下车,这样接下来他就可以步行经过有积水的边。但车会被留在他下车的节点并不会再被使用。
需要特殊说明的是,第二天车会被重置,这意味着:
- 车会在新的出发点被准备好。
- Yazid 不能利用之前在某处停放的车。Yazid 非常讨厌在雨天步行,因此他希望在完成回家这一目标的同时,最小化他步行经过的边的总长度。
请你帮助 Yazid 进行计算。
本题的部分测试点将强制在线,具体细节请见【输入格式】和【子任务】。
输入输出格式
输入格式:
单个测试点中包含多组数据。输入的第一行为一个非负整数\(T\),表示数据的组数。
接下来依次描述每组数据,对于每组数据:
第一行 \(2\) 个非负整数 \(n,m\),分别表示节点数、边数。
接下来 \(m\) 行,每行 \(4\) 个正整数\(u, v, l, a\),描述一条连接节点 \(u, v\) 的、长度为 \(l\)、海拔为 \(a\) 的边。 在这里,我们保证\(1 \leq u,v \leq n\)。
接下来一行 \(3\) 个非负数 \(Q, K, S\) ,其中 \(Q\) 表示总天数,\(K \in {0,1}\) 是一个会在下面被用到的系数,\(S\) 表示的是可能的最高水位线。
接下来 \(Q\) 行依次描述每天的状况。每行 \(2\) 个整数 \(v_0,p_0\)描述一天:
这一天的出发节点为
\(v = (v_0 + K \times \mathrm{lastans} - 1) \bmod n + 1\)。
这一天的水位线为
\(p = (p_0 + K \times \mathrm{lastans}) \bmod (S + 1)\)。
其中 lastans 表示上一天的答案(最小步行总路程)。特别地,我们规定第 \(1\) 天时 lastans = 0。 在这里,我们保证\(1 \leq v_0 \leq n,0 \leq p_0 \leq S\)。
对于输入中的每一行,如果该行包含多个数,则用单个空格将它们隔开。
输出格式:
依次输出各组数据的答案。对于每组数据:
输出 \(Q\) 行每行一个整数,依次表示每天的最小步行总路程。
所有测试点均保证 \(T\leq 3\),所有测试点中的所有数据均满足如下限制:
\(n\leq 2\times 10^5\),\(m\leq 4\times 10^5\),\(Q\leq 4\times 10^5\),\(K\in\left\{0,1\right\}\),\(1\leq S\leq 10^9\)。
对于所有边:\(l\leq 10^4\),\(a\leq 10^9\)。
如果在NOI考场上,这题一定不能挂。
如果你没学过虫狗鼠或者并茶几,那么只要你不写SPFA,在一个多个小时内稳稳拿到离线的65pts是没问题的。
可持久化并茶几我不会,不过虫狗鼠的思路挺简单的,会就是一眼题。
思路:
先按最大生成树建重构树,按照惯例顺手搞一下倍增,然后预处理1为源点的最短路,每次询问直接倍增找到大于水位的节点更新答案即可。
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
const int N=4e5+10;
struct Edge
{
int u,v,w;
bool friend operator <(Edge n1,Edge n2){return n1.w>n2.w;}
}e[N];
int head[N],to[N<<1],Next[N<<1],edge[N<<1],cnt;
void add(int u,int v,int w)
{
to[++cnt]=v,edge[cnt]=w,Next[cnt]=head[u],head[u]=cnt;
}
int F[N],f[N][20],n,m;
int Find(int x){return F[x]=F[x]==x?x:Find(F[x]);}
int dis[N<<1],used[N],poi[N<<1];
int min(int x,int y){return x<y?x:y;}
#define P std::pair <int,int>
std::priority_queue <P,std::vector <P>,std::greater <P> > q;
void disj()
{
memset(dis,0x3f,sizeof(dis));
memset(used,0,sizeof(used));
dis[1]=0;
q.push(std::make_pair(0,1));
while(!q.empty())
{
int u=q.top().second;
q.pop();
if(used[u]) continue;
used[u]=1;
for(int i=head[u];i;i=Next[i])
{
int v=to[i];
if(dis[v]>dis[u]+edge[i])
{
dis[v]=dis[u]+edge[i];
q.push(std::make_pair(dis[v],v));
}
}
}
}
int find(int v,int p)
{
for(int i=19;~i;i--)
if(poi[f[v][i]]>p)
v=f[v][i];
return dis[v];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(head,0,sizeof(head));
memset(f,0,sizeof(f));
memset(poi,0,sizeof(poi));
cnt=0;
scanf("%d%d",&n,&m);
int n_=n;
for(int w,i=1;i<=m;i++)
{
scanf("%d%d%d%d",&e[i].u,&e[i].v,&w,&e[i].w);
add(e[i].u,e[i].v,w),add(e[i].v,e[i].u,w);
}
for(int i=1;i<=n<<1;i++) F[i]=i;
disj();
std::sort(e+1,e+1+m);
for(int i=1;i<=m;i++)
{
int u=e[i].u,v=e[i].v;
int r1=Find(u),r2=Find(v);
if(r1==r2) continue;
F[r1]=F[r2]=f[r1][0]=f[r2][0]=++n;
poi[n]=e[i].w,dis[n]=min(dis[r1],dis[r2]);
}
for(int j=1;j<=19;j++)
for(int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
int lastans=0,q,k,s;
scanf("%d%d%d",&q,&k,&s);
for(int v,p,i=1;i<=q;i++)
{
scanf("%d%d",&v,&p);
v=(v+k*lastans-1)%n_+1;
p=(p+k*lastans)%(s+1);
printf("%d\n",lastans=find(v,p));
}
}
return 0;
}
2018.10.17
NOI2018 D1T1 [NOI2018]归程 解题报告的更多相关文章
- 「NOI2018」屠龙勇士 解题报告
「NOI2018」屠龙勇士 首先对于每个龙用哪个剑砍,我们可以用set随便模拟一下得到. 然后求出拿这个剑砍这条龙的答案 \[ atk_ix-p_iy=a_i \] 其中\(atk_i\)是砍第\(i ...
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- 习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...
- NOIP2016提高组解题报告
NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合
随机推荐
- linux wdcp3 上传大文件 服务器i/o错误
在一次上传大文件时 提示 服务器i/o错误 找了些方法都没有解决 最后发现 wdcp3 面板 默认安装时 web服务器引擎是 nginx + apache 共用 而且 nginx 默认并没与安装 ...
- python字符串编码
python默认编码 python 2.x默认的字符编码是ASCII,默认的文件编码也是ASCII. python 3.x默认的字符编码是unicode,默认的文件编码是utf-8. 中文乱码问题 无 ...
- flask(列表实现)
在 index/views.py 中定义视图函数 在查询的时候,如果用户分类id传0,则不添加分类查询条件 @index_blu.route('/newslist') def get_news_lis ...
- 「LibreOJ#516」DP 一般看规律
首先对于序列上一点,它对答案的贡献只有与它的前驱和后驱(前提颜色相同)构成的点对, 于是想到用set维护每个颜色,修改操作就是将2个set暴力合并(小的向大的合并),每次插入时更新答案即可 颜色数要离 ...
- java stream 处理分组后取每组最大
有一个需求功能:先按照某一字段分组,再按照另外字段获取最大的那个 Map<String, HitRuleConfig> configMap = configList.parallelStr ...
- Ubuntu server中 samba的安装和简单配置
samba是Linux系统上的一种文件共享协议,可以实现Windows系统访问Linux系统上的共享资源,现在介绍一下如何在Ubuntu 14.04上安装和配置samba 工具/原料 Ubuntu ...
- 云计算之路-阿里云上:奇怪的CPU 100%问题
这篇博文记录一下6月1日在阿里云上遇到的奇怪的CPU 100%问题,希望多年以后能真相大白. 那天负载均衡(SLB)中只放了1台云服务器(平时都放2台),由于是节假日,虽然只放了一台,但这台服务器的负 ...
- vue3.0 部署的基础流程
1.创建vue.config.js 主要是负责做设置的 2.修改vue.config.js 参考官方说明: 注意:对于本地开发的同学要注意,你之前在处理网络请求时是在8080端口下请求,现在如果换成了 ...
- QC的使用学习(二)
今日学习清单: 1.Quality Center中左上角选项中(QC 10.0中文版)工具菜单下的自定义中的几个内容,有:用户属性.组.项目用户.模块访问.需求类型.项目列表等.用户属性打开后是对当 ...
- Jmeter从文件中读取参数值
1. 通过函数助手,从本地文件中取值选项->函数助手对话框->选择__CSVRead函数->调用参数其中,函数助手对话框中,第一栏填写本地文件所在地址,第二栏写需要入参的值,有点类似 ...