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代码整合
随机推荐
- MySQL5.7版本安装
安装方式一: ZIP压缩包安装 >>>首先,到MYSQL官网下载.zip格式的MySQL Server的压缩包,根据需要选择x86或x64版. >>>下载需要登录o ...
- 8.1 编写USB鼠标驱动程序,并测试
学习目标:编写USB鼠标驱动程序,并测试(将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键). 一.怎么写USB设备驱动程序?步骤如下: 1. 首先先定义全局变量usb_d ...
- C语言实例解析精粹学习笔记——39(简单的文本编辑器)
实例说明: 编辑一个简单的单行文本编辑器,编辑命令有以下几种:(E.Q.R.I.D) 只有自己在完全空白的情况下编写出来的程序,才是真正自己会的程序,现在所做的,不过是程序的搬运工,把书上的程序搬到网 ...
- POJ2762 单向连通图(缩点+拓扑排序
Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 19552 ...
- R语言学习笔记(十):零碎知识点(21-25)
21--assign() assign函数可以通过变量名的字符串来赋值 > assign('a', 1:3) > a [1] 1 2 3 > b <- c('a') > ...
- 20145202 《Java程序设计》实验五实验报告
一.实验内容 1.用书上的TCP代码,实现服务器与客户端. 2.客户端与服务器连接 3.客户端中输入明文,利用DES算法加密,DES的秘钥用RSA公钥密码中服务器的公钥加密,计算明文的Hash函数值, ...
- xss挑战赛小记 0x02(prompt(1))
0x0O 上次搜xss挑战赛的时候 还找到了一个看上去难度更高的挑战赛 今天做了一下 学到了很多新东西 这个挑战赛能够在页面成功prompt(1)就算过关了 挑战地址 http://prompt.ml ...
- vue2018年5月报错No parser and no file path given
mac电脑直接: rm -rf node_modules rm package-lock.json npm install npm install prettier@~1.12.1 执行完这四个命令, ...
- 使用apache的ab压力测试时失败请求原因
只要出现 Failed requests 就会多出现一行要求失败的各原因的数据统计,分别有 Connect, Length,与 Exception 三种,分别代表的意义为:Connect 无 ...
- LeetCode题目解答
LeetCode题目解答——Easy部分 Posted on 2014 年 11 月 3 日 by 四火 [Updated on 9/22/2017] 如今回头看来,里面很多做法都不是最佳的,有的从复 ...