USACO 2020 February Contest, Gold
USACO 2020 February Contest, Gold
图片懒得上传了,如果影响阅读可以看个人公开笔记
另外就是之前接近一年没登陆,所以消息都没看到,抱歉了。
测试地址
Problem 1. Delegation
题面描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-10myv8p6-1611135874428)(https://i.loli.net/2021/01/20/Tt8W5LVDlkUjBEy.png)]
解题思路
本题是求每次挤奶的最早时间,由于某次挤奶时间可能有依赖,所以可以将依赖看作边,即 a 比 b 至少晚 z 天,就建一条 b --> a 的边,边权为 z ,接下来只要找到所有的入度为 0 的点,从他们出发更新其它所有点的最大路径即可。
根据题意可知我们建立的图中不会有环,但是一个点可能被重复访问多次,而一个点一旦被修改,那么从他出发所有的终点都需要更新,于是可以采用深搜或者广搜,采用深搜剪枝有些麻烦,于是我后来又改成广搜了,改成广搜需要一个标记数组记录待更新节点是否已经在队列中了,如果已经在就无需再次压入了。
但是需要注意的是,一个点第一次被访问时无论是否被更新都要压入队列的,否则无法更新后面的点,因此还需要一个标记数组 vis2 来记录某个点是否被第一次访问。
代码示例
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,c;
const int N = 1e5+10;
const int M = 10*N;
int head[N],ver[M],nex[M],edge[M],tot = 1;
int deg[N];
void addEdge(int x,int y,int z){ver[++tot] = y; edge[tot] = z;nex[tot] = head[x]; head[x] = tot;deg[y]++;
}
int s[N];
queue<int> que;
int vis[N],vis2[N];void solve(){for(int i = 1;i <= n;i++) scanf("%d",s+i);for(int i = 1,x,y,z;i <= c;i++){scanf("%d%d%d",&x,&y,&z);addEdge(x,y,z);}for(int i = 1;i <= n;i++)if(!deg[i]) que.push(i),vis[i] = 1;while(que.size()){int x = que.front(); que.pop();vis[x] = 0,vis2[x] = 1;for(int i = head[x];i;i = nex[i]){int y = ver[i], z = edge[i];if(s[x]+z >= s[y]){if(!vis[y]) que.push(y),vis[y] = 1;s[y] = s[x]+z;}if(!vis2[y] && !vis[y]) que.push(y),vis[y] = 1;}}for(int i = 1;i <= n;i++) printf("%d\n",s[i]);
}
int main(){scanf("%d%d%d",&n,&m,&c);solve();return 0;
}
Problem 2. Help Yourself
题面描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KxTuvHPz-1611135874432)(https://i.loli.net/2021/01/20/Mkmo8xnR12twOC9.png)]
解题思路
假设对于第 i 个线段,在其前面(坐标轴意义的前) a 条线段与其相交,那么该线段对答案的贡献是 2n−1−a2^{n-1-a}2n−1−a ,因为其它 n-1-a 条线段都与其不相交,所以这 a 条线段对这 n-1-a 条线段的所有子集的复杂度之和为 2n−1−a2^{n-1-a}2n−1−a 。
这里求相交的线段数量采用差分+前缀和的思路,在求一维坐标轴上线段相交常用这种方法。
代码示例
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int MOD = 1e9+7;
int n,ans = 0;
int sum[N],l[N],r[N],pw2[N];
void solve(){for(int i = 1;i <= n;i++)cin >> l[i] >> r[i];pw2[0] = 1;for(int i = 1;i < n;i++) pw2[i] = pw2[i-1]*2%MOD;//预处理出 2 的幂for(int i = 1;i <= n;i++){sum[l[i]]++, sum[r[i]]--; //进行差分}for(int i = 1;i <= 2*n;i++) sum[i] += sum[i-1]; //求前缀和for(int i = 1;i <= n;i++) ans = (ans + pw2[n-1-sum[l[i]-1]])%MOD;cout << ans << endl;
}
int main(){scanf("%d",&n);solve();return 0;
}
Problem 3. Delegation
题面描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ctSpL4Yq-1611135874435)(https://i.loli.net/2021/01/20/hNJi51tCTWpq4BV.png)]
解题思路
这道题的难点在于如何判断一个 k 是否合法。
可以通过树上 dp 的做法来判断能否分为若干条长度为 k 的链。不应该将注意力放在边上,而是应该放在点上。无需关注每颗子树如何分割,只需关系到底能不能分割。如果一个子树有 a 个节点,那么这个子树内一定可以分出 a/k 条长度为 k 的链,同时剩下 a%k 条边。所以只需要考虑子树内分割后剩下多少条边,再考虑子树外剩下多少条边,然后看看能否配对即可。
显然树上 dp 可以通过 dfs 来实现,通过一次树上 dp 来求出所需的数据,而后只需 o(N) 一次判断即可。
解决了如何判断 k 是否合法,剩下的就简单了,因为我们很容易就能分析出来,若 k 不是 n-1 的因子,那就无论如何都不能均等分割的,所以实际上最多只需要执行 m 次 check(),其中 m 是 n-1 的因子数目。所以总的时间复杂度为 O(mn)。
代码示例
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int MOD = 1e9+10;
const int M = 2*N;
int n;
int head[N],ver[M],nex[M],tot = 1;
void addEdge(int x,int y){ver[++tot] = y, nex[tot] = head[x]; head[x] = tot;
}
vector<int> num[N];
int sub[N]; // sub[x] 子树 x 的节点个数
void dfs(int x,int fa){sub[x] = 1;for(int i = head[x];i ;i = nex[i]){int y = ver[i];if(y == fa) continue;dfs(y,x);sub[x] += sub[y];num[x].push_back(sub[y]);}if(sub[x] != n) num[x].push_back(n-sub[x]);
}
int cur[N];
bool check(int k){if((n-1)%k) return false;for(int i = 0;i < k;i++) cur[i] = 0;for(int i = 1;i <= n;i++){int cnt = 0;for(auto &t:num[i]){int z = t%k;if(z == 0) continue;if(cur[k-z]) cur[k-z]--,cnt--;else cur[z]++,cnt++;}if(cnt) return false;}return true;
}
void solve(){for(int i = 1,x,y;i < n;i++){scanf("%d%d",&x,&y);addEdge(x,y); addEdge(y,x);}dfs(1,0);for(int i = 1;i < n;i++) cout << check(i);cout << endl;
}
int main(){scanf("%d",&n);solve();return 0;
}
USACO 2020 February Contest, Gold相关推荐
- 【贪心】[USACO 2015 February Contest, Gold]Circular Barn
题目大意 农夫约翰有一个圆形的谷仓,谷仓分成了环形的n(3<=n<=100000)个房间,编号为1,2,--n.每个房间有三个门,两个门通往两个相邻的房间,第三个门朝外.约翰有n头奶牛,乱 ...
- USACO 2020~2021 February Contest GOLD 题解(3)
USACO 2020~2021 二月黄金组 题解(3) 3. Count The Cows As is typical, Farmer John's cows have spread themselv ...
- USACO 2018 February Contest, Silver-Rest Stops
G: Rest Stops 时间限制: 1 Sec 内存限制: 128 MB 提交: 97 解决: 38 [提交][状态][讨论版][命题人:admin] 题目描述 Farmer John and ...
- USACO 2020 December Contest, BronzeProblem 2. Daisy Chains题解
题目描述: 每天,作为她绕农场行走的一部分,奶牛 Bessie 会经过她最喜爱的草地,其中种有 N 朵花(五颜六色的雏菊),编号为1-N(1≤N≤100),排列成一行.花 i 有 pi 朵花瓣(1≤p ...
- USACO 2012 January Contest, Gold Division Solution
T1是一道字符串套dp,当然字符串长度较短于是直接暴力dp即可. T2是一道博弈??反正当爆搜写掉,注意随机化优化. T3是一道树形dp,当然是要挖一些性质的题,敲了近两个小时发现了性质2分钟A了..
- USACO 2020 December Contest, BronzeProblem 1. Do You Know Your ABCs?
QUESTION Farmer John 的奶牛正在 "mooZ" 视频会议平台上举行每日集会.她们发明了一个简单的数字游戏,为会议增添一些乐趣. Elsie 有三个正整数 A.B ...
- USACO 2016 January Contest Gold T2: Radio Contact
题目大意 FJ失去了他最喜欢的牛铃,而Bessie已经同意帮助他找到它!他们用不同的路径搜索农场,通过无线电保持联系.不幸的是,无线电中的电池电量不足,所以他们设法尽可能保持两者位置的距离最小,以节省 ...
- C++ Word Processor | USACO 2020 January Contest
题目描述 奶牛 Bessie 正在完成她的写作课的一篇作文.由于她写字很难看,她决定用一个文字处理器来输入这篇作文. 这篇作文共有 N 个单词(1≤N≤100),用空格分隔.每个单词的长度在 1 到 ...
- USACO 2018 FEBURARY CONTEST :SILVER T1
USACO 2018 February Contest, Silver Problem 1. Rest Stops Farmer John and his personal trainer Bessi ...
最新文章
- Java源码下载和阅读(JDK1.8/Java 11)
- 全球及中国胶合板行业产量规模与营运能力研究报告2022版
- 镜像电流源特点_9000大型地网变频大电流接地特性测量系统介绍
- c语言兔子繁殖问题分析和递归方程,经典的兔子生兔子问题(C#递归解法)
- _用WSL,MobaXterm,Cmder配置linux开发环境
- ORB-SLAM2和ORB-SLAM的区别
- cfd软件对电脑配置要求_这种网格划分策略,让洁净和空调CFD实施周期压缩至0.3倍...
- 《和平精英》崩了 官方回应:受运营商网络波动影响 正在修复
- 天津理工大学计算机调剂信息,天津理工大学2020考研调剂信息
- 小米成立“线下业务委员会”;暴风 TV 回应员工讨薪;超 98% 安卓应用不安全 | 极客头条...
- 离开北上广的互联网工程师最终都去了哪里?
- vscode 头文件包含问题_VScode编译C++ 头文件显示not found的问题
- android打开wav声音
- 联想微型计算机扬天s711怎么拆,如何优雅的拆掉一体机电脑 Lenovo 联想 扬天S5250...
- 百度文库付费文档免费下载
- 更新cuda驱动10.0==>11.2
- C语言中的指针加减偏移量
- Laravel 加密
- 数据驱动背景下的设备故障预测及诊断方法
- 《Android源码设计模式》之策略模式