前言:考试挂了很多分,难受……

---------------------

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+数学(高精))的更多相关文章

  1. 6月28日考试 题解(GCD约分+动态规划+树状数组二维偏序)

    前言:考的一般般吧……T3暴力没打上来挺可惜的,到手的75分没了. ---------------------------------- T1 [JZOJ4745]看电影 Description 听说 ...

  2. 3月21日考试 题解(数据结构+区间DP+贪心)

    前言:T3写挂了,有点难受. --------------- T1 中位数 题意简述:给你一段长度为$n$的序列,分别输出$[1,2k-1]$的中位数$(2k-1\leq n)$. --------- ...

  3. HDU 3586 二分答案+树形DP判定

    HDU 3586 『Link』HDU 3586 『Type』二分答案+树形DP判定 ✡Problem: 给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏 ...

  4. BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP

    BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP Description Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的 ...

  5. BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP

    题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...

  6. BZOJ2282 SDOI2011消防/NOIP2007树网的核(二分答案+树形dp)

    要求最大值最小容易想到二分答案.首先对每个点求出子树中与其最远的距离是多少,二分答案后就可以标记上一些必须在所选择路径中的点,并且这些点是不应存在祖先关系的.那么如果剩下的点数量>=3,显然该答 ...

  7. BZOJ4985 评分(二分答案+树形dp)

    首先二分答案简化一下问题,现在只有0和1了,要求最后剩下的是1.再简化一下考虑没有已固定的位置怎么做.考虑每个位置由其合并到的位置连边,显然这样形成了一棵三叉树.设f[i]为使得某位置为1其子树至少要 ...

  8. hdu3586 Information Disturbing[二分答案+树形DP]

    给定 n 个节点的树,边有权值.1 号点是根,除了 1 号点外的度数为 1 的节点是叶子.要求切断所有叶子和 1 号点之间的联系,切断一条边要花费这条边上权值对应的代价,要求总的代价不超过 m.在满足 ...

  9. 7月13日考试 题解(DFS序+期望+线段树优化建图)

    T1 sign 题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和.N<=10000 水题.考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多 ...

随机推荐

  1. java 面向对象(三十六):泛型五 通配符

    1.通配符的使用 /* 通配符的使用 通配符:? 类A是类B的父类,G<A>和G<B>是没关系的,二者共同的父类是:G<?> */ @Test public voi ...

  2. redis入门指南(五)—— 复制与哨兵

    写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 一.复制 1.在复制中,数据库分为两类,一类主数据库,一类从数据库,主库用来读写,从库用来读,主 ...

  3. 定时器之Timer

    Timer中的TimerTask就是一个线程,可以一直执行下去的.可以使用Timer类的cancel方法来结束.-------------------------------------------- ...

  4. Ubuntu14.04 安装VMware tools

    Ubuntu14.04 安装VMware tools 方法一: 1. 在VMware 11(个人的测试环境为vm 11版本)下安装Ubuntu镜像:ubuntu-14.04.1-desktop-amd ...

  5. 直接在x86硬件上显示图片(无os)

    1 任务 为了学习计算机底层和os,我给自己布置了一个任务:在x86硬件上,使用c和nasm来显示一张bmp图片.完成这个任务,前后估计花了2个月的业余时间. 这个任务涉及了很多知识点,包括:启动区. ...

  6. xenomai内核解析之信号signal(一)---Linux信号机制

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 1. Linux信号 1.1注册信号处理函数 ...

  7. C++ 优先队列priority_queue用法

    头文件:#include<queue> 操作: top 访问队头 empty 队列是否为空 size 返回队列元素个数 push 插入元素到队尾 pop 弹出队头 swap 交换内容 定义 ...

  8. 【最短路+bfs+缩点】Paint the Grid Reloaded ZOJ - 3781

    题目: Leo has a grid with N rows and M columns. All cells are painted with either black or white initi ...

  9. 简单理解:数据库的一致性与四种隔离级别(+MySQL实现)

    并行数据库存在着几种常见不一致问题: 1.更新丢失:两个并发的写进程同时修改某内容,一个没修改完提交之后另一个又提交,导致其覆盖了第一个提交的写进程内容. 2.脏读:一个操作读到了另外一个操作没有提交 ...

  10. python基础--深浅copy(重点)

    在此申明一下,博客参照了https://www.cnblogs.com/jin-xin/,自己做了部分的改动 深浅copy(重点) 先问问大家,什么是拷贝?拷贝是音译的词,其实他是从copy这个英文单 ...