HGOI 20190708 题解
Problem A 拿出勇气吧
幸运数字每一位是$4$或者$7$,现在给出一个数字每位数位上数的和为n,求出最小的幸运数n
对于100%的数据,$n\leq 10^6$
Sol : 显然本题要求数的长度尽可能短,于是显然是先放$7$放$4$并且$7$放在较低位。
这就等价于求不定方程$4x + 7y = n $的最小整数解x,然后只要延续输出x个4,y个7即可。
只需要做一次exgcd就可以求出。
复杂度应该是答案的长度 $O(length)$
# include <bits/stdc++.h>
# define int long long
using namespace std;
struct node {
int x,y; bool flag;
};
int exgcd(int a,int b,int &x,int &y)
{
if (b==) {
x=;y=;
return a;
}
int g=exgcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*x;
return g;
}
node getmin(int a,int b,int c)
{
int x,y; int g=exgcd(a,b,x,y);
if (c%g!=) return (node){-,-,false};
int k=c/g,ga=a/g,gb=b/g;
x=(x*k%gb+gb)%gb;
y=(c-a*x)/b;
return (node){x,y,true};
}
signed main()
{
int n;scanf("%d",&n);
node t=getmin(,,n);
for (int i=;i<=t.x;i++) printf("");
for (int i=;i<=t.y;i++) printf("");
return ;
}
Courage.cpp
Problem B 生死之对决
幸运数字每一位是$4$或者$7$,给出$ p \in [pl,pr] \in Z,v \in [vl,vr] \in Z $ 且$p,v$ 在所属区间等概率出现。
求出区间$[min\{v,p\} , max \{v,p\}]$包含幸运数字恰好是$k$个的概率。
对于100%的数据$1 \leq ql \leq qr \leq 10^9,1 \leq vl \leq vr \leq 10^9,1 \leq k \leq 10^3 $
Sol :首先在$[1,10^9]$的幸运数字是$2^1 + 2^2 + ... + 2^9 = 1022$个,所以我们可以基于枚举每一个幸运数字对答案造成的贡献(用乘法原理)来进行计数。
设排序后的幸运数字为$p_i (1\leq i \leq 1022)$ 那么我们枚举第$p_i $到$p_{i+k-1}$这$k$个幸运数字在$[min\{v,p\} , max\{v,p\}]$区间内。
所以有$min\{p,v\} \in [p_{i-1} +1 , p_i] ,max\{p,v\} \in [p_{i+k-1},p_{i+k}-1]$
为了拆掉$min,max$所以我们要讨论$p,v$的大小关系。
当$p \leq v$ 时显然有 $p \in [p_{i-1} +1 , p_i] , v \in [p_{i+k-1},p_{i+k}-1] $
当$p \geq v$ 时显然有 $v \in [p_{i-1} +1 , p_i] , p \in [p_{i+k-1},p_{i+k}-1] $
注意到上述我们在$p = v $的时候可能会重复计算,而且当且仅当$ k = 1$的时候出现,所以需要特判。
# pragma GCC optimize()
# include <bits/stdc++.h>
# define int long long
using namespace std;
const int N=2e3+;
int p[N];
int n;
void getlucky(int num,int lim)
{
if (num>lim) return;
if (num!=) p[++n]=num;
getlucky(num*+,lim);
getlucky(num*+,lim);
}
signed main()
{
getlucky(,2e9); int pl,pr,vl,vr,k;
scanf("%lld%lld%lld%lld%lld",&pl,&pr,&vl,&vr,&k);
sort(p+,p++n);
p[n+]=2e9+; int ans=;
for (int i=;i<=n;i++) {
if (min(p[i],pr)-max(p[i-]+,pl)+>=&&min(p[i+k]-,vr)-max(p[i+k-],vl)+>=) {
ans+=(min(p[i],pr)-max(p[i-]+,pl)+)*(min(p[i+k]-,vr)-max(p[i+k-],vl)+);
}
if (min(p[i+k]-,pr)-max(p[i+k-],pl)+>=&&min(p[i],vr)-max(p[i-]+,vl)+>=) {
ans+=(min(p[i+k]-,pr)-max(p[i+k-],pl)+)*(min(p[i],vr)-max(p[i-]+,vl)+);
}
}
if (k==) {
for (int i=;i<=n;i++)
if (p[i]>=vl&&p[i]<=vr&&p[i]>=pl&&p[i]<=pr) ans--;
}
printf("%.12lf\n",(double)ans/(double)(vr-vl+)/(double)(pr-pl+));
return ;
}
Match.cpp
Problem C 最后的结局
一棵树上的点和父亲之间可能是存在魔法边和普通边,定义合法三元组$(i,j,k)$表示从$i$出发到$j$路径上和$i$出发到$k$路径上都至少存在一条魔法边。
注意到不同的$(i,j,k)$都算不同的合法三元组。计算这棵树中合法三元组的数目。
对于100%的数据 $ 1 \leq n \leq 10^5 $
Sol : 直接树形DP即可,设$f_u$ 表示节点 $u$ 跑到所有节点的路径中含有魔法边的节点个数。
第一次跑dfs从儿子更新到父亲,转移方程是 $f_{u}= \sum\limits_{v \in u_{son}} \left\{\begin{matrix} size_{v}&(u,v) \ is \ magic \ edge \\ f_{v}& (u,v) \ isn't \ magic \ edge \end{matrix}\right.$
第二次跑dfs从父亲更新到儿子,转移方程是$f_v = \left\{\begin{matrix} f_u & (u,v)\ isn't \ magic \ edge\\ n-size_v & (u,v) \ is \ magic \ edge \end{matrix}\right.$
复杂度$O(n)$
# pragma GCC optimize()
# include<bits/stdc++.h>
# define int long long
using namespace std;
const int N=1e5+;
struct rec{
int pre,to,w;
}a[N<<];
int f[N],tot,head[N],size[N],n;
bool check(int x) {
while (x) {
if (!(x%==||x%==)) return false;
x/=;
}
return true;
}
void adde(int u,int v,int w)
{
a[++tot].pre=head[u];
a[tot].to=v;
a[tot].w=w;
head[u]=tot;
}
void dfs1(int u,int fa)
{
size[u]=; f[u]=;
for (int i=head[u];i;i=a[i].pre) {
int v=a[i].to; if (v==fa) continue;
dfs1(v,u); size[u]+=size[v];
if (a[i].w==) f[u]+=size[v];
else f[u]+=f[v];
}
}
void dfs2(int u,int fa)
{
for (int i=head[u];i;i=a[i].pre) {
int v=a[i].to; if (v==fa) continue;
if (a[i].w==) f[v]+=n-size[v];
else f[v]=f[u];
dfs2(v,u);
}
}
signed main()
{
// freopen("ending.in","r",stdin);
// freopen("ending.out","w",stdout);
scanf("%lld",&n);
for (int i=;i<n;i++) {
int u,v,w; scanf("%lld%lld%lld",&u,&v,&w);
if (check(w)) adde(u,v,),adde(v,u,);
else adde(u,v,),adde(v,u,);
}
dfs1(,); dfs2(,);
int ans=;
for (int i=;i<=n;i++) ans+=(long long)f[i]*(f[i]-);
printf("%lld\n",ans);
return ;
}
Ending.cpp
HGOI 20190708 题解的更多相关文章
- HGOI 20181028 题解
HGOI 20181028(复赛备考) /* 真是暴力的一天,最后一题MLE?由于数组开得太大了!!! 270滚粗 考场上好像智商高了很多?!(假的) */ sol:暴力求解,然后没有数据范围吐槽一下 ...
- HGOI 20190310 题解
/* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...
- HGOI 20190303 题解
/* 记一串数字真难. 5435 今天比赛又是hjcAK的一天. 今天开题顺序是312,在搞T1之前搞了T3 昨天某谷月赛真是毒瘤. 但是讲评的同学不错,起码T4看懂了... 构造最优状态然后DP的思 ...
- HGOI 20180224 题解
/* The Most Important Things: ljc chat with fyh on QQTa说期末考Ta数学74分感觉不好但是我觉得fyh是地表最强的鸭~~(of course en ...
- HGOI 20190218 题解
/* 又是AK局... hjc又双叒叕AK了... Hmmm...我侥幸 */ Problem A card 给出无序序列a[]可以选择一个数插入到合适的位置作为一次操作,至少多少次操作后可以把序列变 ...
- HGOI 20190217 题解
/* for me,开训第一天 /beacuse 文化课太差被抓去补文化课了... 看一眼题 : AK局? 但是,Wa on test #10 in problem C 290! (就差那么一咪咪) ...
- HGOI 20181103 题解
problem:把一个可重集分成两个互异的不为空集合,两个集合里面的数相乘的gcd为1(将集合中所有元素的质因数没有交集) solution:显然本题并不是那么容易啊!考场上想了好久.. 其实转化为上 ...
- HGOI 20181101题解
/* 又是爆0的一天(不知道今年高考难不难,反正今天(信息学)真的难!) */ solution:对于两个数相加,有一个显然的结论就是要么不进位(相对于位数大的),要么(进最多一位) 然后对于整个数组 ...
- HGOI 20191108 题解
Problem A 新婚快乐 一条路,被$n$个红绿灯划分成$n+1$段,从前到后一次给出每一段的长度$l_i$,每走$1$的长度需要$1$分钟. 一开始所有红绿灯都是绿色的,$g$分钟后所有红绿灯变 ...
随机推荐
- MySQL中出现的小问题
./scripts/mysql_install_db: line 249: /app/mysql/bin/my_print_defaults: cannot execute binary fileNe ...
- Java小程序—录屏小程序(上半场)
做软件的三个步骤: (1)做什么? (2)怎么做? (3)动手做! ok,我们今天要做的是一个录屏软件,那怎么做呢?首先,我们小时候都玩过一种小人书,就是当你快速翻动书页时,书中的人物就会活灵活现的动 ...
- redis 学习(1)-- redis 安装与启动
redis 学习(1)-- redis 安装与启动 redis 特性 关于 redis 的介绍网上已经有很多信息了,这里我就不在详细说明了.介绍一下几个鲜明特性: 1.速度快 官方称可以达到10W的q ...
- Elasticsearch入门教程(五):Elasticsearch查询(一)
原文:Elasticsearch入门教程(五):Elasticsearch查询(一) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...
- [转载]static in Java
来源:https://www.cnblogs.com/chenssy/p/3386721.html 一. static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现 ...
- JavaScript学习基础
基本语法 JavaScript语法和Java语言类似,每个语句以 : 结束,语句块用 {...}包起来.JavaScript并不强制要求在每个语句的结尾加: ,但是建议都加上,不给自己找麻烦. ...
- vue项目-axios封装、easy-mock使用
vue全家桶概括下来就是 项目构建工具(vue-cli) 路由(vue-router) 状态管理(vuex) http请求工具 vue有自己的http请求工具插件vue-resource,但是vue2 ...
- Java中的字符串常量池,栈和堆的概念
问题:String str = new String(“abc”),“abc”在内存中是怎么分配的? 答案是:堆内存.(Tips:jdk1.8 已经将字符串常量池放在堆内存区) 题目考查的为Ja ...
- mysql数据库查询过程探究和优化建议
查询过程探究 我们先看一下向mysql发送一个查询请求时,mysql做了什么? 如上图所示,查询执行的过程大概可分为6个步骤: 客户端向MySQL服务器发送一条查询请求 服务器首先检查查询缓存,如果命 ...
- 韦东山嵌入式Linux学习笔记01--转载: 板子ping不通PC怎么办
请参考链接:https://blog.csdn.net/u013490896/article/details/71250060 我的环境: window 10 jz2440 v3 我采用的连接方式如下 ...