NOIP 2013 day1
tags:
- 模拟
- 快速幂
- 逆序对
- 树状数组
- 归并排序
- 最小生成树
- lca
- 倍增
categories: - 信息学竞赛
- 总结
tex live 2017.iso
转圈游戏
火柴排队
货车运输
转圈游戏
solution
就是要求让一个人在一个圈上走一定步数, 问最后在哪里.例如走\(10^k\)次, 一次走\(\text{m}\)步, 初始时在\(\text{x}\), 圈长\(\text{n}\), 那么它最后的位置就是:
\]
那么直接用快速幂暴力求出这个式子的值.
code
#include<cstdio>
int n,m,k,x;
long long pow(int a,int b){
long long ans=1ll,bas=a;
while(b){
if(b&1)ans*=bas;
ans%=n;
if(!bas)return ans;
bas*=bas;bas%=n;
if(!bas)return false;
b>>=1;
}
return ans;
}
int main(){
scanf("%d%d%d%d",&n,&m,&k,&x);
long long ans=x,mm=pow(10,k);
ans+=m*mm%n;
ans%=n;
printf("%lld\n",ans);
return 0;
}
火柴排队
solution
其实就是将其中一个通过交换两个相邻的元素使得变化后的序列与另一个序列最相近, 问操作次数.
其实就是使得两个序列中最大的元素位置相同, 第二大的元素位置也相同, 第三大的元素位置相同......那么元素的具体大小其实根本无所谓, 只需要知道元素之间的大小关系, 所以可以先将两个序列离散化, 然后找到其中一个的元素在另一个中的位置, 记为序列\(\text{c}\), 经离散后的序列记为\(\text{a,b}\), 那么我们进行的交换操作, 实际上就是将\(\text{c}\)变为序列\(1,2,\cdots ,n\), 这样其实就是将\(\text{b}\)变成\(\text{a}\).
Code
#include<algorithm>
#include<cstdio>
#define N 100005
#define mod 99999997
int ans;
int n,u[N];
int a[N],b[N];
int e[N],f[N],g[N];
void mergesort(int l,int r){
if(l==r)return;
int mid,i,j,k;
mid=(l+r)>>1;
mergesort(l,mid);
mergesort(mid+1,r);
i=l,j=mid+1,k=l;
while(i<=mid&j<=r)
if(g[i]>=g[j])u[k++]=g[j++],ans+=(mid-i+1)%mod,ans%=mod;
else u[k++]=g[i++];
while(i<=mid)u[k++]=g[i++];
while(j<=r)u[k++]=g[j++];
for(i=l;i<=r;i++)g[i]=u[i];
}
struct Node{
int val,pos;
bool operator<(const Node& s)const{
return val<s.val;
}
}c[N],d[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int i=1;i<=n;++i)scanf("%d",&b[i]);
for(int i=1;i<=n;++i)c[i]=(Node){a[i],i};
for(int i=1;i<=n;++i)d[i]=(Node){b[i],i};
std::sort(c+1,c+n+1);std::sort(d+1,d+n+1);
for(int i=1;i<=n;++i)e[c[i].pos]=i;
for(int i=1;i<=n;++i)f[d[i].pos]=i;
for(int i=1;i<=n;++i)g[i]=c[f[i]].pos;
mergesort(1,n);
printf("%d",ans);
return 0;
}
货车运输
这个经典的题目不知道做了多少遍了, 这次做还是发现了一些问题.
Solution
需要使得图上两点之间经过路径上边的最小值最大, 首先将原图变成最大生成树, 因为两点之间经过的最小边权最大的路径必然存在在最大生成树上. 记两点之间的路径的转折点为\(\text{lca}\)(最近公共祖先),在最大生成树上两点\(\text{u,v}\)之间路径上边的最小值就是\(\text{u}\)到\(\text{lca}\)路径上边的最小值或者是\(\text{u}\)到\(\text{lca}\)路径上边的最小值.
- 需要用倍增来加速\(\text{lca}\)的求解, 也可以用树链剖分, 用\(f(u,i)\)表示从\(\text{u}\)向上第\(2^i\)个点是哪个点.递推公式为:
\]
- 求\(树上两点之间路径的最小值\)可以使用\(\text{RMQ}\)算法, 用\(d(u,i)\)表示从$\text{u}以上\(2^i\)个点路径的最小值, 那么递推公式为:
\]
\(f(u,0)\)和\(d(u,0)\)可以在dfs中直接得到, \(f(u,i)\)和\(d(u,i)\)需要递推来获得.
Code
#include<algorithm>
#include<cstdio>
#define N 500005
#define inf 0x3f3f3f3f
int n,m,q;
int fa[N];
int dep[N];
int f[N][20];
int d[N][20];
int min(int i,int j){
return i>j?j:i;
}
int find(int s){
if(fa[s]!=s)fa[s]=find(fa[s]);
return fa[s];
}
struct E{
int u,v,cost;
void Init(){
scanf("%d%d%d",&u,&v,&cost);
}
bool operator<(const E&s)const{
return cost>s.cost;
}
void print(){
printf("%d %d %d\n",u,v,cost);
}
}edge[N];
int head[N],tot;
struct Edge{
int v,c,nxt;
}e[N];
void AddEdge(int u,int v,int c){
e[++tot]=(Edge){v,c,head[u]};head[u]=tot;
e[++tot]=(Edge){u,c,head[v]};head[v]=tot;
}
void dfs(int x,int fath){
f[x][0]=fath;dep[x]=dep[fath]+1;
for(int i=head[x];i;i=e[i].nxt){
if(e[i].v==fath)continue;
d[e[i].v][0]=e[i].c;dfs(e[i].v,x);
}
}
int Lca(int u,int v){
int cha;
if(dep[u]<dep[v])std::swap(u,v);
for(int i=19;i>-1;--i)
if(dep[f[u][i]]>=dep[v])
u=f[u][i];
for(int i=19;i>-1;--i)
if(f[u][i]!=f[v][i])
u=f[u][i],v=f[v][i];
if(u!=v)return f[u][0];
return u;
}
int Ans(int u,int v){
if(u==v)return inf;
int ans=inf;
for(int i=19;i>-1;--i)
if(dep[f[u][i]]>=dep[v])
ans=min(d[u][i],ans),u=f[u][i];
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)edge[i].Init();
for(int i=1;i<=n;++i)fa[i]=i;
std::sort(edge+1,edge+m+1);int f1,f2,flag=0;
for(int pos=1,f1,f2,i=1;i<n;++i){
for(f1=find(edge[pos].u),f2=find(edge[pos].v);f1==f2;++pos,f1=find(edge[pos].u),f2=find(edge[pos].v))
if(pos>m){flag=1;break;}
if(flag)break;
fa[f1]=f2;
AddEdge(edge[pos].u,edge[pos].v,edge[pos].cost);
//edge[pos].print();
}
dfs(1,0);
for(int i=1;i<20;++i)
for(int j=1;j<=n;++j)
f[j][i]=f[f[j][i-1]][i-1];
for(int i=1;i<20;++i)
for(int j=1;j<=n;++j)
d[j][i]=min(d[j][i-1],d[f[j][i-1]][i-1]);
scanf("%d",&q);
int u,v,lca;
while(q--){
scanf("%d%d",&u,&v);
lca=Lca(u,v);
if(find(u)!=find(v))printf("-1\n");
else printf("%d\n",min(Ans(u,lca),Ans(v,lca)));
}
return 0;
}
NOIP 2013 day1的更多相关文章
- NOIP 2013 货车运输【Kruskal + 树链剖分 + 线段树 】【倍增】
NOIP 2013 货车运输[树链剖分] 树链剖分 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在 ...
- Luogu 1979 NOIP 2013 华容道(搜索,最短路径)
Luogu 1979 NOIP 2013 华容道(搜索,最短路径) Description 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面 ...
- [Noip 2013 Day1-3] 货车运输 做法总结
[Noip 2013 Day1-3] 货车运输 做法总结 Online Judge:Luogu-1967 Label:启发式合并,离线,整体二分,按秩合并,倍增,最大生成树 打模拟离线赛时做到,顺便总 ...
- luoguP6754 [BalticOI 2013 Day1] Palindrome-Free Numbers
目录 luoguP6754 [BalticOI 2013 Day1] Palindrome-Free Numbers 简述题意: Solution: Code luoguP6754 [BalticOI ...
- P6753 [BalticOI 2013 Day1] Ball Machine
P6753 [BalticOI 2013 Day1] Ball Machine 题意 给你一个树,每次从根节点放一个求,如果其子节点有空这个球会向下滚,若有多个节点为空则找儿子中以子树内编号的最小值为 ...
- NOIP 2013 提高组 day1 T2 火柴排队 归并 逆序对
描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑i=1n(ai−bi)2∑i=1n(ai−bi) ...
- noip 2013 提高组 day1
1.转圈游戏: 解析部分略,快速幂就可以过 Code: #include<iostream> #include<fstream> using namespace std; if ...
- 【CodeVS 3290】【NOIP 2013】华容道
http://codevs.cn/problem/3290/ 据说2013年的noip非常难,但Purpleslz学长还是AK了.能A掉这道题真心orz. 设状态$(i,j,k)$表示目标棋子在$(i ...
- Noip 2016 Day1 题解
老师让我们刷历年真题, 然后漫不经心的说了一句:“你们就先做做noip2016 day1 吧” ...... 我还能说什么,,,,,老师你这是明摆着伤害我们啊2333333333 预计分数:100+2 ...
随机推荐
- React注释
React中注释有以下三种 var content = ( <Nav> {/* 一般注释, 用 {} 包围 */} <Person /* 多 行 注释 */ name={window ...
- [转]Android 如何根据网络地址获取网络图片方法
http://blog.csdn.net/xiazdong/article/details/7724103 目录(?)[-] h2pre namecode classhtml stylefont-we ...
- PowerDesigner 技巧【3】
一.PowerDesigner导出所有SQL脚本: 一般的导出SQL脚本只需要下面两个步骤: 1.database->change current DBMS(选择需要导出的数据库类型): 2.d ...
- Linux服务器上nginx安装的完整步骤
1.环境准备: 服务器系统版本:CentOS 6.5 nginx软件版本:nginx-1.13.9 2.资源准备: nginx下载地址:http://nginx.org/download/nginx- ...
- All you need to know about sorting in Postgres
按:之前看pg的执行计划,多次看到不同的排序方式,但不知何意.偶遇此篇讲解pg执行计划三种排序方式,备忘一下. Sorting Sorting is one of the most fundament ...
- POJ3164:Command Network(有向图的最小生成树)
Command Network Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 20766 Accepted: 5920 ...
- Ubuntu Android adb调试无法识别设备 -- List of devices attached ???????????? no permissions
在Ubuntu下做Android开发, 使用adb devices调试的时候出现在面的错误: 这个问题之前就出现过的,突然就忘了,Mark一下.在网上找了一下,基本上是一些比较麻烦的办法,但是在我的记 ...
- python删除文件
删除qq文件夹中2013年12-31之前的文件import os import time import datetime timeline = datetime.datetime(,,) tl = t ...
- zjoi2018day2游记
因为是在主场作战,所以就不需要东奔西跑了, 继一试爆炸以后,一个月来,感觉没有什么特别的进步,期间考了将近一个月的试, 每次如果拿应该拿的分的话,是不会太差的,但是从来没有发挥好过,就没有我认为正常过 ...
- bzoj 1131 [POI2008]Sta 树形dp 转移根模板题
[POI2008]Sta Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1889 Solved: 729[Submit][Status][Discu ...