NOIP模拟赛-2018.11.6
NOIP模拟赛
今天想着反正高一高二都要考试,那么干脆跟着高二考吧,因为高二的比赛更有技术含量(我自己带的键盘放在这里).
今天考了一套英文题?发现阅读理解还是有一些困难的.
T1:有$n$个点,$m$天,第$[1,m]$天每天会把最大公约数是$m-i+1$的数连边,给出$q$组询问,询问给出的两点最早被连接起来是什么时候.$n,m,q<=10^5$
一开始以为是一道求$gcd$的签到题...后来发现还可以这样:$3->6,6->8$,所以不用等到最后一天$3,8$就连通了.
首先可以想到枚举每一天,把$gcd$为这个数的数对两两连边合并并查集,但是查询的时候就不知道是哪天连起来的了,所以可以用$Kruscal$重构树,每次合并时加一个新的点来中转.但是枚举数对的复杂度非常高,有一种思路是枚举质数对并乘上$gcd$,可是打表发现这个范围内的质数有点多...
这时可以发现一个很奇妙的性质:如果两个数同时是$d$的倍数,那么它们被连接起来不会晚于$d$的出现时间,为什么?依旧采取最大公约数的表示形式:
$$a=xd,b=yd,(x,y)不保证互质$$ $$a=xd,b=yd$$ $$a=x_1qd,b=y_1qd \quad (x_1,y_1)=1$$ $$(x_1d,y_1d)=d$$ $$(a,x_1d)=x_1d,(b,y_1d)=y_1d$$ $$min\left \{ d,x_1d,x_2d\right \}=d$$
既然$d$的倍数都会被连起来,我们又是每次建立新点来连接,就可以直接把所有倍数都连接到新点上,不用枚举数对了.
树建好之后每次询问在树上倍增找$LCA$即可.
# include <cstdio>
# include <iostream>
# include <cstring>
# include <string>
# include <algorithm>
# include <cmath>
# define R register int
# define ll long long using namespace std; const int maxn=;
int x,n,m,q,h,firs[maxn],f[maxn][];
int dep[maxn],v[maxn],nod,F[maxn];
struct edge
{
int too,nex;
}g[maxn*+]; int read ()
{
int x=,f=;
char c=getchar();
while (!isdigit(c)) { if(c=='-') f=-f; c=getchar(); }
while (isdigit(c)) x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
} void add (int x,int y)
{
g[++h].nex=firs[x];
g[h].too=y;
firs[x]=h;
} int father (int x)
{
if(x!=F[x]) return F[x]=father(F[x]);
return x;
} void dfs (int x)
{
int j;
for (R i=firs[x];i;i=g[i].nex)
{
j=g[i].too;
if(dep[j]) continue;
f[j][]=x;
dep[j]=dep[x]+;
for (R k=;k<=;++k)
f[j][k]=f[ f[j][k-] ][k-];
dfs(j);
}
} int lca (int x,int y)
{
if(dep[x]>dep[y]) swap(x,y);
for (R i=;i>=;--i)
if(dep[y]-(<<i)>=dep[x]) y=f[y][i];
if(x==y) return x;
for (R i=;i>=;--i)
{
if(f[x][i]==f[y][i]) continue;
x=f[x][i];
y=f[y][i];
}
return f[x][];
} int main()
{
scanf("%d%d%d",&n,&m,&q);
for (R i=;i<=n;++i)
F[i]=i;
nod=n;
for (R i=m;i>=;--i)
{
nod++;
F[nod]=nod;
v[nod]=m-i+;
for (R j=;j*i<=n;++j)
{
x=father(i*j);
if(x==nod) continue;
add(nod,x);
add(x,nod);
F[x]=nod;
}
}
dep[nod]=;
dfs(nod);
for (R i=;i<=q;++i)
{
int x,y;
x=read(),y=read();
printf("%d\n",v[ lca(x,y) ]);
}
fclose(stdin);
fclose(stdout);
return ;
}
pictionary
T2:有$n$座楼,每座有一个高度和金币数,可以从任意楼开始跳,每次只能跳到右边不低于当前楼高的楼上,可以在任意楼停下,问获得的总金币数大于等于$k$的方案数.$n<=40$
考场写了搜索,还有一种奇怪的用$map$做$dp$的做法,正解是折半搜索,分别找到前后两部分的答案数,然后记录前半部分以高度$i$结尾,收益是$j$的方案数以及后半部分以高度$i$开始,收益是$j$的方案数,排序后对于前者找到后者的匹配区间,好像很快啊.
# include <cstdio>
# include <iostream>
# include <cstring>
# include <string>
# include <algorithm>
# include <cmath>
# include <vector>
# include <map>
# define R register int
# define ll long long using namespace std; const int maxn=;
int n;
ll ans,k,h[maxn],g[maxn],f[maxn];
vector <ll> v[maxn];
map <ll,int> m[maxn]; int read ()
{
int x=,f=;
char c=getchar();
while (!isdigit(c)) { if(c=='-') f=-f; c=getchar(); }
while (isdigit(c)) x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
} int main()
{
freopen("san.in","r",stdin);
freopen("san.out","w",stdout); scanf("%d%lld",&n,&k);
for (R i=;i<=n;++i)
scanf("%lld%lld",&h[i],&g[i]);
for (R i=;i<=n;++i)
{
if(m[i][ g[i] ]==)
v[i].push_back(g[i]);
m[i][ g[i] ]++;
for (R j=i+;j<=n;++j)
{
if(h[j]<h[i]) continue;
int s=v[i].size();
for (R k=;k<s;++k)
{
ll x=v[i][k]+g[j];
if(m[j][x]==)
v[j].push_back(x);
m[j][x]+=m[i][ v[i][k] ];
}
}
}
for (R i=;i<=n;++i)
{
int siz=v[i].size();
for (R j=;j<siz;++j)
if(v[i][j]>=k) ans+=m[i][ v[i][j] ];
}
printf("%lld",ans);
fclose(stdin);
fclose(stdout);
return ;
} /*
4 6
2 1
6 3
7 2
5 6 */
san-40
T3:https://www.luogu.org/problemnew/show/P4441
$Cena$不能编译$string$类型...?直接全$T$了...
可以尝试带着$string$一起$dp$,保存目前在哪个点,有多少个未匹配的左括号的最长长度,$string$中保存这个答案,显然这样是比较慢的...在洛谷上也没过。题解是$dp$时只求长度,最终拿最长长度倒推回去找答案,听起来很有道理的样子.
# include <cstdio>
# include <iostream>
# include <cstring>
# include <string>
# include <algorithm>
# include <cmath>
# define R register int
# define ll long long using namespace std; int read ()
{
int x=,f=;
char c=getchar();
while (!isdigit(c)) { if(c=='-') f=-f; c=getchar(); }
while (isdigit(c)) x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
} const int dir[]={-,,};
int a[][],pos,x;
int dp[][][];
string s[][][],c;
string ans;
int len; string tr (string a,string b)
{
if(a.length()>b.length()) return a;
else if(a.length()<b.length()) return b;
return min(a,b);
} int main()
{
int n,m;
cin>>n>>m;
for (R i=n;i>=;--i)
{
cin>>c;
while(c.length()==) cin>>c;
c=' '+c;
for (R j=;j<=m;++j)
{
if(c[j]=='.') a[i][j]=;
else if(c[j]=='(') a[i][j]=;
else if(c[j]==')') a[i][j]=-;
else if(c[j]=='*') a[i][j]=;
else pos=j;
}
}
for (R i=;i<=m+;++i)
a[n+][i]=;
memset(dp[],,sizeof(dp[]));
dp[][][pos]=;
for (R i=;i<=n+;++i)
{
int no=i&;
int las=no^;
memset(dp[no],,sizeof(dp[no]));
for (R j=;j<=m;++j)
for (R k=;k<=m;++k)
s[no][j][k]="";
for (R j=;j<=m;++j)
for (R k=;k<=m;++k)
{
if(dp[las][j][k]<) continue;
for (R d=;d<;++d)
{
x=k+dir[d];
if(x<=||x>m) continue;
if(a[i][x]==)
{
if(j==) ans=tr(ans,s[las][j][k]);
continue;
}
if(a[i][x]==)
{
if(dp[no][j][x]<dp[las][j][k])
{
dp[no][j][x]=dp[las][j][k];
s[no][j][x]=s[las][j][k];
}
if(dp[no][j][x]==dp[las][j][k]) s[no][j][x]=tr(s[no][j][x],s[las][j][k]);
}
if(a[i][x]==-)
{
if(j==) continue;
if(dp[no][j-][x]<dp[las][j][k]+)
{
dp[no][j-][x]=dp[las][j][k]+;
s[no][j-][x]=s[las][j][k]+")";
}
if(dp[no][j-][x]==dp[las][j][k]+) s[no][j-][x]=tr(s[no][j-][x],s[las][j][k]+")");
}
if(a[i][x]==)
{
if(dp[no][j+][x]<dp[las][j][k]+)
{
dp[no][j+][x]=dp[las][j][k]+;
s[no][j+][x]=s[las][j][k]+"(";
}
if(dp[no][j+][x]==dp[las][j][k]+) s[no][j+][x]=tr(s[no][j+][x],s[las][j][k]+"(");
}
}
}
}
cout<<ans.length()<<endl<<ans;
return ;
}
Retro
---shzr
NOIP模拟赛-2018.11.6的更多相关文章
- NOIP模拟赛-2018.11.7
NOIP模拟赛 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 编译之前另存一份,听说如果敲 ...
- NOIP模拟赛-2018.11.5
NOIP模拟赛 好像最近每天都会有模拟赛了.今天从高二逃考试跑到高一机房,然而高一也要考试,这回好像没有拒绝的理由了. 今天的模拟赛好像很有技术含量的感觉. T1:xgy断句. 好诡异的题目,首先给出 ...
- NOIP模拟赛-2018.10.22
模拟赛 今天第一节课是历史,当然是不可能上的,一来到机房发现今天高二考试... 老师说以后可能还要给高一考...那还不如现在跟着做好了,毕竟在学长学姐中垫底显得没那么丢人 这套题风格挺奇怪的...为什 ...
- 11/1 NOIP 模拟赛
11.1 NOIP 模拟赛 期望得分:50:实际得分:50: 思路:暴力枚举 + 快速幂 #include <algorithm> #include <cstring> #in ...
- 10.17 NOIP模拟赛
目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...
- 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) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 10.16 NOIP模拟赛
目录 2018.10.16 NOIP模拟赛 A 购物shop B 期望exp(DP 期望 按位计算) C 魔法迷宫maze(状压 暴力) 考试代码 C 2018.10.16 NOIP模拟赛 时间:2h ...
随机推荐
- Oracle总结之plsql编程(基础八)
原创作品,转自请注明出处:https://www.cnblogs.com/sunshine5683/p/10328524.html 一.函数 1.函数是可以返回一个特定的数据,函数的创建中必须包含re ...
- Power of Matrix(uva11149+矩阵快速幂)
Power of Matrix Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit St ...
- 【10-2】复杂业务状态的处理(从状态者模式到FSM)
一.概述 我们平常在开发业务模块时,经常会遇到比较复杂的状态转换.比如说用户可能有新注册.实名认证中.已实名认证.禁用等状态,支付可能有等待支付.支付中.已支付等状态.OA系统里的状态处理就更多了. ...
- Linux常用基本命令(cat)
cat命令 作用:连接多个文件并且打印到屏幕输出,或者重定向到其他文件,也可以用来查看显示单个文件,或者多个文件. 格式: cat [option] [file] 1,最简单的用法,直接跟文件名称,查 ...
- 转载文章CSS3的calc()使用
calc()对大家来说,或许很陌生,不太会相信calc()是css中的部分.因为看其外表像个函数,既然是函数为何又出现在CSS中呢?这一点也让我百思不得其解,今天有一同事告诉我,说CSS3中有一个属性 ...
- 说说对npm的开发模式和生产模式的理解
nodejs这些年的发展非常快,相信没有哪个前端不知道的了,npm也成为了前端开发中经常用到了的一个命令.那么npm不是只用一个 "npm install xxx"命令就够了吗?实 ...
- JS--我发现,原来你是这样的JS(引用类型不简单[上篇],且听我娓娓道来)
一.介绍 没错,这是第五篇,到了引用类型,这次要分成两次博文了,太多内容了,这是前篇,篇幅很长也很多代码,主要讲引用类型和常用的引用类型,代码试验过的,老铁没毛病. 坚持看坚持写,不容易不容易,希望大 ...
- npm、cnpm、bower安装区别
简单地说,就是帮你下载好你需要的css或者js库,而且三者功能也都是一样的.那为什么要下载这3个不同的呢?据说npm容易被墙……而cnpm是淘宝的镜像,所以通常用cnpm代替npm.至于bower,是 ...
- FineReport单行与数据库交互的方法
1. 问题描述 我们在做一张报表填报的时候经常会遇到需要在一行进行添加动作,将该行数据直接与数据库交互,执行存储过程过程.我们可以通过每一行增加帆软“插入”按钮实现插入动作,并且在控件事件中增加和 ...
- 《Inside C#》笔记(一) .NET平台
C# 基于.NET运行时,所以有必要首先对.NET以及C#与.NET平台的关系有一定的了解. 一 .NET平台 .NET背后的基本思想是将原本独立工作的设备.网络服务整合在一个统一的平台上,从而可以为 ...