NOIp模拟赛 旅游


很神奇的一道题,金策大爷给的题解:

什么叫神犇什么叫蒟蒻?
IOI冠军的一句基本相同让我思考了一下午。
看完了题解我就想都没想开始用遍历二分图搞,但是搞到了65分后就总是会WA掉7组。
然后仔细的看了看std,位运算上对几处做了常数上的优化,读起来异常麻烦,到最后看懂他在干什么了。但是总是不理解。
下午浪费了两节英语课思考原理,总之想明白了。
我简单说一下我的想法。
首先考虑如果一条路径的所有边权的gcd为$d$,那么不管正着走反着走或者绕上几圈,其总路径和一定为$kd$,$k$为任意正整数。
这一点学过gcd应该都很好想到。那么很显然的一件事就是如果一张图中两个相通的点,从一个点到另一个点的总路径和也一定为$kd$,$d$为这个连通分量里所有边权的gcd。同样的,如果需要把答案mod$K$,只需要$d=gcd(K,d)$即可,最后的答案一定是$d$或者0。这点转化是这道题的第一步。但不是最重要的一步。
这时候就把问题转化为了从$node_i$到$node_j$是否存在一条路径,使得其总长为$cK$,$c$为任意正整数。如果存在,显然答案为0,如果不存在,那么答案就是$d$。同时,需要提前用并查集判断连通性。
首先,考虑$K$为奇数的情况,在这种情况下,只要两点联通,答案一定为0,因为如果K为奇数,而假设从$node_i$到$node_j$的最短路径为$h$,那么一定存在一个数$b$使得$bh=cK$,如果想到了这点。就能拿到20分的部分分。
然后我们是否应该考虑$K$为偶数的情况?
并不,相对来说有更通用的情况。回到前面,我们已经得出了如果把总路径$modK$,那么一定存在一种方案使得从$node_i$到$node_j$的长度为$d$,这时候如果$K$为$d$的奇数倍,那么显然答案为0。
再思考,既然$d$为这个连通分量里所有边权的gcd,这也就意味着所有边的边权都是$d$的整数倍,也就是说所有边都可以拆成任意整数个边权为$d$的边。而如果存在一个数使得$hd==cK$,那么答案就是0。
那么是否可以把每个点拆为$node_i$和$node_{i+N}$,其中的两个点集之间相连的边的长度是奇数个$d$,而任意一个点集里的点之间的边都是偶数个$d$,这个显然可以用并查集维护。
这时候如果$node_i$和$node_j$位于一个点集,显然其是存在为0的答案。
但是除此之外,还存在特殊的情况。如果从一个点到另一个点既存在奇数个$d$的路径,也存在偶数个$d$的路径。怎么处理?
这时候只需要把这个联通块标记即可,这个连通块的任意两点之间到达的答案均为0。
//NOIp 0924 pod
//by Cydiater
//2016.9.24
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <string>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
#define FILE "pod"
const int MAXN=1e6+5;
const int oo=0x3f3f3f3f;
inline int read(){
char ch=getchar();int x=0,f=1;
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int N,M,Q,LINK[MAXN],len=0,f[MAXN],f2[MAXN],tol[MAXN];
struct edge{
int x,y,next,v;
}e[MAXN<<1];
bool OK[MAXN];
namespace solution{
inline void insert(int x,int y,int v){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].v=v;e[len].x=x;}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int getf(int k){
if(f[k]==k) return k;
f[k]=getf(f[k]);
return f[k];
}
int getf2(int k){
if(f2[k]==k) return k;
f2[k]=getf2(f2[k]);
return f2[k];
}
void merge(int x,int y,int v){
x=getf(x);y=getf(y);
if(tol[x]!=0)v=gcd(v,tol[x]);
if(tol[y]!=0)v=gcd(v,tol[y]);
tol[x]=v;f[y]=x;
}
int merge2(int x,int y,int v){
if(v==1){
if(getf2(x)==getf2(y)) return 0;
f2[getf2(x)]=getf2(y+N);
f2[getf2(y)]=getf2(x+N);
}else{
if(getf2(x)==getf2(y+N)) return 0;
f2[getf2(x)]=getf2(y);
f2[getf2(x+N)]=getf2(y+N);
}
return 1;
}
void init(){
N=read();M=read();Q=read();
memset(tol,0,sizeof(tol));
up(i,1,N){
f[i]=i;f2[i]=i;
f2[i+N]=i+N;
}
up(i,1,M){
int x=read(),y=read(),v=read();
insert(x,y,v);insert(y,x,v);
merge(x,y,v);
}
up(i,1,M<<1){
int x=e[i].x,y=e[i].y,v=e[i].v;
int d=tol[getf(e[i].x)];
int flag=merge2(x,y,(v/d)%2);
if(!flag)OK[getf(x)]=1;
i+=1;
}
}
void slove(){
while(Q--){
int x=read(),y=read(),K=read();
if(getf(x)!=getf(y)) puts("NIE");//unconnect
else{
int d=gcd(K,tol[getf(x)]);
if((K/d)&1) puts("0");
else{
if(OK[getf(x)]) puts("0");
else{
if(getf2(x)==getf2(y)) puts("0");//same color
else printf("%d\n",d);
}
}
}
}
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
using namespace solution;
init();
slove();
return 0;
}
NOIp模拟赛 旅游的更多相关文章
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
- 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #52 - Thinking Bear #1 (NOIP模拟赛)
A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...
随机推荐
- jquery的offset与position的区别
这里offset取得是屏幕影藏的y轴的距离➕元素距离屏幕的y轴的距离. 而postion取得的则是,上一个父元素(包含postion定位的)的距离
- [jQuery EasyUI系列] 创建增删改查应用
一.数据收集并妥善管理数据是网络应用共同的必要.CRUD允许我们生产页面列表并编辑数据库记录. 本文主要演示如何使用jQuery EasyUI实现CRUD DataGrid. 将使用到的插件有: da ...
- Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo
更新了xcode后使用goland运行项目时提示 Agreeing to the Xcode/iOS license requires admin privileges, please re-run ...
- mailto: HTML e-mail 链接
转载: http://www.haorooms.com/post/mailto_link_html 什么是mailto链接? mailto链接是一种html链接,能够设置你电脑中邮件的默认发送信息.但 ...
- SpringMVC学习--参数绑定
spring参数绑定过程 从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上.springmvc中,接收页面提交的数据是通过方法形参来接收 ...
- ThinkPHP上传返回 “文件上传保存错误!”
这个问题,最终的由于 Local.class.php中的iconv('utf-8', 'gb2312' ,$filename)的问题 因为我上传的文件名中有 "-" 这个符号. i ...
- iOS开发小技巧--获取自定义的BarButtonItem中的自定义View的方法(customView)
如果BarButtonItem是通过[[UIBarButtonItem alloc] initWithCustomView:(nonnull UIView *)]方法设置的.某些情况下需要修改BarB ...
- 【BZOJ 4636】蒟蒻的数列
http://www.lydsy.com/JudgeOnline/problem.php?id=4636 DCrusher贡献的题目 看了他的博客,有两种做法,动态开点线段树和离线操作离散化区间线段树 ...
- LRU设计
list是双向链表,map保存key对应到list中的迭代器的位置,list保存<key,value> class LRUCache{ public: LRUCache(int capac ...
- 让nodeJS支持ES6的词法----babel的安装和使用
要使用Babel, 我们需要nodeJS的环境和npm, 主要安装了nodeJS, npm就默认安装了 , 现在安装nodeJS很简单了, 直接下载安装就好了: 安装es-checker 在使用Bab ...