3月28日考试 题解(二分答案+树形DP+数学(高精))
前言:考试挂了很多分,难受……
---------------------
T1:防御
题意简述:给一条长度为$n$的序列,第$i$个数的值为$a[i]$。现让你将序列分成$m$段,且让和最小的一段尽可能得大。求这个最大值。
-------------------------
题意很明显,最小值最大。不难想到二分答案,为节约时间我们在$(minn,sum)$这个区间内维护。考虑用前缀和维护$sum$。(不知道为什么不用前缀和挂掉50分……。
代码:
- //二分答案 nlogn=4e6
- #include<bits/stdc++.h>
- #define int unsigned long long
- using namespace std;
- int n,m,a[],sum[],minn=0x3f3f3f3f;
- inline int read()
- {
- int x=,f=;char ch=getchar();
- while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
- while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
- return x*f;
- }
- bool check(int x)
- {
- int jishu=,last=;
- for (int i=;i<=n;i++)
- {
- if (sum[i]-sum[last]>=x)
- {
- last=i;
- jishu++;
- }
- if(jishu==m) return true;
- }
- return false;
- }
- signed main()
- {
- n=read(),m=read();
- for (int i=;i<=n;i++)
- {
- a[i]=read();
- sum[i]=sum[i-]+a[i];
- minn=min(minn,a[i]);
- }
- int l=minn,r=sum[n];
- while(l<=r)
- {
- int mid=(l+r)/;
- if (check(mid)) l=mid+;
- else r=mid-;
- }
- printf("%ld",r);
- return ;
- }
T2:切树游戏
题意简述:现在有一颗黑白树。每个节点为黑点或白点。现在让你删去一些边,使每个连通块中恰好有一个黑点。求方案数。答案对1e9+7取模。
------------------
树形DP。
我们设$f[i][0]$为以i为根的树删去一些子树后不含黑点的方案数,设$f[i][1]$为以i为根的树删去一些子树后含黑点的方案数。
则有:
$f[u][1]=f[u][1]*(f[v][0]+f[v][1])+f[u][0]*f[v][1]$
$f[u][0]=f[u][0]*(f[v][0]+f[v][1])$
先对$f[u][1]$进行解释:若当前$u$所在的连通块已含有黑点,若子树含黑点,则删去;若子树不含黑点,则连上。又根据乘法原理得第一部分式子。若当前$u$所在的节点不含黑点,那么只有当子树含黑点时,才连上。由此得出$f[u][1]=f[u][1]*(f[v][0]+f[v][1])+f[u][0]*f[v][1]$。$f[u][0]$同理。
注意两条方程不能调换顺序,因为$f[u][1]$要用到上一阶段$f[i][0]$的值。
对于树形dp我们用dfs递归实现。
代码:
- #include<bits/stdc++.h>
- #define int long long
- using namespace std;
- const int maxn=2e5+;
- const int MOD=1e9+;
- int head[maxn*],cnt,f[maxn][];
- int a[maxn],n;
- struct node
- {
- int next,to;
- }edge[maxn];
- inline int read()
- {
- int x=,f=;char ch=getchar();
- while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
- while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
- return x*f;
- }
- void add(int from,int to)
- {
- edge[++cnt].next=head[from];
- edge[cnt].to=to;
- head[from]=cnt;
- }
- void dfs(int u,int fa)
- {
- for(int i=head[u];i;i=edge[i].next)
- {
- int v=edge[i].to;
- if(v==fa) continue;
- dfs(v,u);
- f[u][]=(f[u][]*(f[v][]+f[v][])%MOD+f[u][]*f[v][]%MOD)%MOD;
- f[u][]=(f[u][]*(f[v][]+f[v][]))%MOD;
- }
- }
- signed main()
- {
- n=read();
- for (int i=;i<=n;i++)
- {
- int p=read();p++;
- add(i,p);add(p,i);
- }
- for (int i=;i<=n;i++) a[i]=read(),f[i][a[i]]=;
- dfs(,);
- printf("%ld",f[][]);
- return ;
- }
T3;二叉树
题意简述:现在给你含有$n$个节点的二叉树,问组成不同二叉树的方案数。每个点认为是互不相同的。$n\leq 10000$
-----------------
假设我们已经将一个节点定为根。
那么子树组成方案为$f[0]\times f[i-1]+f[1]\times f[i-2]+…+f[i-1]\times f[0]$。
符合卡特兰数的定义。
因为n的数据范围较大,要用到高精度。(卡特兰数有通项公式,但我并不会高精度除法QAQ。
代码:
- #include<bits/stdc++.h>
- using namespace std;
- int a[][];
- int c[];
- void cheng(int f,int h)
- {
- for (int i=;i<=a[f][];i++)
- {
- int x=;
- for (int j=;j<=a[h][];j++)
- {
- c[i+j-]=a[f][i]*a[h][j]+x+c[i+j-];
- x=c[i+j-]/;
- c[i+j-]%=;
- }
- c[i+a[h][]]=x;
- }
- int lenc=;
- while(!c[lenc]) lenc--;
- c[]=lenc;
- }
- void jia(int f)
- {
- int x=;
- int len=;
- while(len<=c[]||len<=a[f][])
- {
- a[f][len]+=c[len]+x;
- x=a[f][len]/;
- a[f][len]%=;
- len++;
- }
- a[f][len]=x;
- if (x) a[f][]+=len;
- else a[f][]+=len-;
- }
- int main()
- {
- int n;cin>>n;
- a[][]=;a[][]=;
- a[][]=;a[][]=;
- for (int i=;i<=n;i++)
- {
- for (int j=;j<=i-;j++)
- {
- memset(c,,sizeof(c));
- cheng(j,i--j);
- jia(i);
- }
- }
- int len=;
- while(!a[n][len]) len--;
- for (int i=len;i>=;i--) printf("%d",a[n][i]);
- return ;
- }
3月28日考试 题解(二分答案+树形DP+数学(高精))的更多相关文章
- 6月28日考试 题解(GCD约分+动态规划+树状数组二维偏序)
前言:考的一般般吧……T3暴力没打上来挺可惜的,到手的75分没了. ---------------------------------- T1 [JZOJ4745]看电影 Description 听说 ...
- 3月21日考试 题解(数据结构+区间DP+贪心)
前言:T3写挂了,有点难受. --------------- T1 中位数 题意简述:给你一段长度为$n$的序列,分别输出$[1,2k-1]$的中位数$(2k-1\leq n)$. --------- ...
- HDU 3586 二分答案+树形DP判定
HDU 3586 『Link』HDU 3586 『Type』二分答案+树形DP判定 ✡Problem: 给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏 ...
- BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP
BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP Description Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的 ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
- BZOJ2282 SDOI2011消防/NOIP2007树网的核(二分答案+树形dp)
要求最大值最小容易想到二分答案.首先对每个点求出子树中与其最远的距离是多少,二分答案后就可以标记上一些必须在所选择路径中的点,并且这些点是不应存在祖先关系的.那么如果剩下的点数量>=3,显然该答 ...
- BZOJ4985 评分(二分答案+树形dp)
首先二分答案简化一下问题,现在只有0和1了,要求最后剩下的是1.再简化一下考虑没有已固定的位置怎么做.考虑每个位置由其合并到的位置连边,显然这样形成了一棵三叉树.设f[i]为使得某位置为1其子树至少要 ...
- hdu3586 Information Disturbing[二分答案+树形DP]
给定 n 个节点的树,边有权值.1 号点是根,除了 1 号点外的度数为 1 的节点是叶子.要求切断所有叶子和 1 号点之间的联系,切断一条边要花费这条边上权值对应的代价,要求总的代价不超过 m.在满足 ...
- 7月13日考试 题解(DFS序+期望+线段树优化建图)
T1 sign 题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和.N<=10000 水题.考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多 ...
随机推荐
- 基层教师 - CMD命令之net命令与IPC连接
1)建立空连接: net use \\IP\ipc$ "" /user:"" (一定要注意:这一行命令中包含了3个空格) 2)建立非空连接: net use \ ...
- LintCode笔记 - 82.落单的数
这一题相对简单,但是代码质量可能不是很好,我分享一下我的做题笔记以及做题过程给各位欣赏,有什么不足望各位大佬指出来 原题目,各位小伙伴也可以试着做一下 . 落单的数 中文English 给出 * n ...
- shell进阶篇之字典和数组结合应用案例
# 现在我们用字典结合数组来实现一个简单的远程管理机 远程管理机的需求:现在需要在一个管理机上实现下列两点内容: 1.需要可以实时查看现有项目运行状态 2.远程登陆任意一台机器 备注:现有的机器如下 ...
- 数据可视化之powerBI基础(七)一文带你熟悉PowerBI建模视图中的功能
https://zhuanlan.zhihu.com/p/67316729 PowerBI 3月的更新,正式发布了建模视图,而之前只是预览功能.新的建模视图到底有什么用,下面带你认识一下它的主要功能. ...
- 数据可视化之分析篇(二)Power BI 数据分析:客户购买频次分布
https://zhuanlan.zhihu.com/p/100070260 商业数据分析通常都可以简化为对数据进行筛选.分组.汇总的过程,本文通过一个实例来看看PowerBI是如何快速完成整个过程的 ...
- python 之 编码
本节内容 编码回顾 编码转换 Python的bytes类型 编码回顾 在备编码相关的课件时,在知乎上看到一段关于Python编码的回答 这哥们的这段话说的太对了,搞Python不把编码彻底搞明白,总有 ...
- linux专题(二):走近Linux系统 (2020-04-08 10:08)
http://dwz.date/UDf 走近Linux系统 开机登录 开机会启动许多程序.它们在Windows叫做"服务"(service),在Linux就叫做"守护进程 ...
- Windows下配置ChromeDriver
1.查看自己chrome浏览器的版本. 浏览器地址栏输入以下地址 chrome://version 2.通过自己的版本下载相应的chromedriver.exe 下载地址:http://npm.tao ...
- Dresdon简介
很久没有写文章了.这几年经历了很多事情:离开VMware的不舍,拿到融资的开心,重回VMware的亲切,以及不再争强好胜,只做自己喜欢事情的平和. 可以说,我是幸运的:我这一辈子都在选择,而不是被迫接 ...
- ES6语法——Promise对象
一.概念 Promise是异步编程的一种解决方案(解决回调地狱的问题),是一个能够获取异步操作信息的对象.Promise的内部保存着某个未来才会结束的事件(通常是一个异步操作) 二.特点 1.Prom ...