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)$

  1. # include <bits/stdc++.h>
  2. # define int long long
  3. using namespace std;
  4. struct node {
  5. int x,y; bool flag;
  6. };
  7. int exgcd(int a,int b,int &x,int &y)
  8. {
  9. if (b==) {
  10. x=;y=;
  11. return a;
  12. }
  13. int g=exgcd(b,a%b,x,y);
  14. int t=x;x=y;y=t-a/b*x;
  15. return g;
  16. }
  17. node getmin(int a,int b,int c)
  18. {
  19. int x,y; int g=exgcd(a,b,x,y);
  20. if (c%g!=) return (node){-,-,false};
  21. int k=c/g,ga=a/g,gb=b/g;
  22. x=(x*k%gb+gb)%gb;
  23. y=(c-a*x)/b;
  24. return (node){x,y,true};
  25. }
  26. signed main()
  27. {
  28. int n;scanf("%d",&n);
  29. node t=getmin(,,n);
  30. for (int i=;i<=t.x;i++) printf("");
  31. for (int i=;i<=t.y;i++) printf("");
  32. return ;
  33. }

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$的时候出现,所以需要特判。

  1. # pragma GCC optimize()
  2. # include <bits/stdc++.h>
  3. # define int long long
  4. using namespace std;
  5. const int N=2e3+;
  6. int p[N];
  7. int n;
  8. void getlucky(int num,int lim)
  9. {
  10. if (num>lim) return;
  11. if (num!=) p[++n]=num;
  12. getlucky(num*+,lim);
  13. getlucky(num*+,lim);
  14. }
  15. signed main()
  16. {
  17. getlucky(,2e9); int pl,pr,vl,vr,k;
  18. scanf("%lld%lld%lld%lld%lld",&pl,&pr,&vl,&vr,&k);
  19. sort(p+,p++n);
  20. p[n+]=2e9+; int ans=;
  21. for (int i=;i<=n;i++) {
  22. if (min(p[i],pr)-max(p[i-]+,pl)+>=&&min(p[i+k]-,vr)-max(p[i+k-],vl)+>=) {
  23. ans+=(min(p[i],pr)-max(p[i-]+,pl)+)*(min(p[i+k]-,vr)-max(p[i+k-],vl)+);
  24. }
  25. if (min(p[i+k]-,pr)-max(p[i+k-],pl)+>=&&min(p[i],vr)-max(p[i-]+,vl)+>=) {
  26. ans+=(min(p[i+k]-,pr)-max(p[i+k-],pl)+)*(min(p[i],vr)-max(p[i-]+,vl)+);
  27. }
  28. }
  29. if (k==) {
  30. for (int i=;i<=n;i++)
  31. if (p[i]>=vl&&p[i]<=vr&&p[i]>=pl&&p[i]<=pr) ans--;
  32. }
  33. printf("%.12lf\n",(double)ans/(double)(vr-vl+)/(double)(pr-pl+));
  34. return ;
  35. }

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)$

  1. # pragma GCC optimize()
  2. # include<bits/stdc++.h>
  3. # define int long long
  4. using namespace std;
  5. const int N=1e5+;
  6. struct rec{
  7. int pre,to,w;
  8. }a[N<<];
  9. int f[N],tot,head[N],size[N],n;
  10. bool check(int x) {
  11. while (x) {
  12. if (!(x%==||x%==)) return false;
  13. x/=;
  14. }
  15. return true;
  16. }
  17. void adde(int u,int v,int w)
  18. {
  19. a[++tot].pre=head[u];
  20. a[tot].to=v;
  21. a[tot].w=w;
  22. head[u]=tot;
  23. }
  24. void dfs1(int u,int fa)
  25. {
  26. size[u]=; f[u]=;
  27. for (int i=head[u];i;i=a[i].pre) {
  28. int v=a[i].to; if (v==fa) continue;
  29. dfs1(v,u); size[u]+=size[v];
  30. if (a[i].w==) f[u]+=size[v];
  31. else f[u]+=f[v];
  32. }
  33. }
  34. void dfs2(int u,int fa)
  35. {
  36. for (int i=head[u];i;i=a[i].pre) {
  37. int v=a[i].to; if (v==fa) continue;
  38. if (a[i].w==) f[v]+=n-size[v];
  39. else f[v]=f[u];
  40. dfs2(v,u);
  41. }
  42. }
  43. signed main()
  44. {
  45. // freopen("ending.in","r",stdin);
  46. // freopen("ending.out","w",stdout);
  47. scanf("%lld",&n);
  48. for (int i=;i<n;i++) {
  49. int u,v,w; scanf("%lld%lld%lld",&u,&v,&w);
  50. if (check(w)) adde(u,v,),adde(v,u,);
  51. else adde(u,v,),adde(v,u,);
  52. }
  53. dfs1(,); dfs2(,);
  54. int ans=;
  55. for (int i=;i<=n;i++) ans+=(long long)f[i]*(f[i]-);
  56. printf("%lld\n",ans);
  57. return ;
  58. }

Ending.cpp

HGOI 20190708 题解的更多相关文章

  1. HGOI 20181028 题解

    HGOI 20181028(复赛备考) /* 真是暴力的一天,最后一题MLE?由于数组开得太大了!!! 270滚粗 考场上好像智商高了很多?!(假的) */ sol:暴力求解,然后没有数据范围吐槽一下 ...

  2. HGOI 20190310 题解

    /* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...

  3. HGOI 20190303 题解

    /* 记一串数字真难. 5435 今天比赛又是hjcAK的一天. 今天开题顺序是312,在搞T1之前搞了T3 昨天某谷月赛真是毒瘤. 但是讲评的同学不错,起码T4看懂了... 构造最优状态然后DP的思 ...

  4. HGOI 20180224 题解

    /* The Most Important Things: ljc chat with fyh on QQTa说期末考Ta数学74分感觉不好但是我觉得fyh是地表最强的鸭~~(of course en ...

  5. HGOI 20190218 题解

    /* 又是AK局... hjc又双叒叕AK了... Hmmm...我侥幸 */ Problem A card 给出无序序列a[]可以选择一个数插入到合适的位置作为一次操作,至少多少次操作后可以把序列变 ...

  6. HGOI 20190217 题解

    /* for me,开训第一天 /beacuse 文化课太差被抓去补文化课了... 看一眼题 : AK局? 但是,Wa on test #10 in problem C 290! (就差那么一咪咪) ...

  7. HGOI 20181103 题解

    problem:把一个可重集分成两个互异的不为空集合,两个集合里面的数相乘的gcd为1(将集合中所有元素的质因数没有交集) solution:显然本题并不是那么容易啊!考场上想了好久.. 其实转化为上 ...

  8. HGOI 20181101题解

    /* 又是爆0的一天(不知道今年高考难不难,反正今天(信息学)真的难!) */ solution:对于两个数相加,有一个显然的结论就是要么不进位(相对于位数大的),要么(进最多一位) 然后对于整个数组 ...

  9. HGOI 20191108 题解

    Problem A 新婚快乐 一条路,被$n$个红绿灯划分成$n+1$段,从前到后一次给出每一段的长度$l_i$,每走$1$的长度需要$1$分钟. 一开始所有红绿灯都是绿色的,$g$分钟后所有红绿灯变 ...

随机推荐

  1. sql实现同时向主表和子表插入数据方法

    使用sql语句实现同时向主表和子表插入数据方法: Oracle: -- oracle创建sequence create sequence SEQ_test minvalue 1 maxvalue 99 ...

  2. linux基础命令<二>

    1.关机 init 0   poweroff   halt  shutdown –h   now 2.重启 init 6   reboot  shutdown –r now 3.查询都有那些用户在系统 ...

  3. python-连接mysql实例

    import pymysql # 创建连接 conn = pymysql.connect(host='192.168.71.140', port=3306, user='root', passwd=' ...

  4. mybatis N+1问题解决

    关联嵌套查询 示例: <resultMap id="blogResult" type="Blog"> <association propert ...

  5. 剑指offer-左旋转字符串-知识迁移能力-python

    题目描述汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=”abcX ...

  6. python:enumerate 函数

    说明 enumerate()是python的内置函数: 对于一个可迭代的(iterable)/可遍历的对象(如列表.字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值 多用于 ...

  7. python 中的 [:-1] 和 [::-1]

    1.案例解释 a='python' b=a[::-1] print(b) #nohtyp c=a[::-2] print(c) #nhy #从后往前数的话,最后一个位置为-1 d=a[:-1] #从位 ...

  8. 109、Secret的使用场景 (Swarm16)

    参考https://www.cnblogs.com/CloudMan6/p/8082429.html   我们可以用secret管理任何敏感数据.这些敏感数据是容器在运行时需要的.同时我们又不想把这些 ...

  9. cookie和session的详解和区别

    会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...

  10. Java高并发程序设计学习笔记(二):多线程基础

    转自:https://blog.csdn.net/dataiyangu/article/details/86226835# 什么是线程?线程的基本操作线程的基本操作新建线程调用run的一种方式调用ru ...