AtCoder Grand Contest 017 题解
A - Biscuits
题目:
给出 \(n\) 个物品,每个物品有一个权值。
问有多少种选取方式使得物品权值之和 \(\bmod\space 2\) 为 \(p\).
\(n \leq 50\)
题解:
记录一下 \(n\) 个物品中权值是奇数的数的个数.
分类讨论一下喽...
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;static char ch;static bool flag;flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 128;
int n,p,x,a,b;
int main(){
read(n);read(p);
rep(i,1,n){
read(x);
if(x & 1) ++a;
else ++b;
}
if(a == 0){
if(p == 0) printf("%lld\n", 1LL << n);
else puts("0");
}else printf("%lld\n", 1LL <<n-1);
return 0;
}
B - Moderate Differences
题目:
一个长为 \(n\) 的序列,给出左右两端的元素,问能否在中间的 \(n-2\) 个位置之中填入一些元素使得所有相邻元素的差的绝对值在 \([c,d]\) 内。
\(n \leq 500000, a,b,c,d \leq 10^9\)
题解:
我们将所有的填入与前一项差在某一范围内的元素视作将这个元素改变的限制。
我们知道这个元素一定是经过若干次上升和若干次下降后到达右端。
所以我们可以枚举上升多少次,相应的就知道了下降多少次。
这样我们可以计算出来上升的区间范围和下降的区间范围。
计算一下就好了.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(ll &x){
x=0;static char ch;static bool flag;flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
int main(){
ll n,a,b,c,d;read(n);read(a);read(b);read(c);read(d);
if(n == 1){
if(a != b) puts("NO");
else puts("YES");
}else{-- n;
for(ll i = 0, j;i <= n;++i){
j = n - i;
ll x = i*c, y = i*d;
ll X = j*c + b-a, Y = j*d + b-a;
if(y < X) continue;
if(Y < x) continue;
puts("YES");return 0;
}puts("NO");
}
return 0;
}
C - Snuke and Spells
题目:
在一个长度为 \(i\) 的序列中施展咒语会消掉所有的值为 \(i\) 的项。
带动态修改某一点元素值地查询需要改掉多少数才能使得序列可以通过不断施展咒语而消掉。
\(n,m \leq 200000\)
题解:
我们分别考虑每个元素。
我们发现如果第 \(i\) 个元素有 \(s_i\) 中。
那么当长度到达 \(i\) 时下一步就会到达 \(i - s_i\)。
我们用一条 \([i-s_i,i]\) 的线段来表示这么一个数。
容易发现只有当所有 \([0,n]\) 的所有点之间的线段都被覆盖的时候才可行。
那么一次修改的话我们又最多只能多覆盖一条线段。
(最多使\([i-s_i,i] \to [i-s_i-1,i]\))
所以最小的修改此时就是没有被覆盖的线段条数。
记录一下 \(num_i\) 表示覆盖了 \([i-1,i]\) 的线段条数即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;static char ch;static bool flag;flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 200010;
int a[maxn],ws[maxn],num[maxn];
int main(){
int n,m;read(n);read(m);
rep(i,1,n) read(a[i]),ws[a[i]] ++ ;
int ans = 0;
rep(i,1,n) if(ws[i]){
num[max(i-ws[i]+1,1)] ++ ;
num[min(i+1,n+1)] -- ;
}
rep(i,1,n) num[i] += num[i-1],ans += (num[i] == 0);
while(m--){
int t,y,x;read(t);read(y);
x = a[t];a[t] = y;
if((x-ws[x]+1) >= 1 && (x-ws[x]+1) <= n){
if(-- num[x-ws[x]+1] == 0) ++ ans;
}-- ws[x];++ ws[y];
if((y-ws[y]+1) >= 1 && (y-ws[y]+1) <= n){
if(++ num[y-ws[y]+1] == 1) -- ans;
}printf("%d\n",ans);
}
return 0;
}
D - Game on Tree
题目:
给定一个 \(n\) 个点的树。Alice和Bob在上面玩游戏。
一次操作切断一条边,没有 \(1\) 节点的部分被删掉
无法操作就输. \(n \leq 100000\)
题解:
雅礼集训讲课原题。
考虑子树的合并就好了。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;static char ch;static bool flag;flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 100010;
struct Edge{
int to,next;
}G[maxn<<1];
int head[maxn],cnt;
void add(int u,int v){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
}
int fa[maxn],g[maxn];
void dfs(int u){
g[u] = 0;
for(rg i = head[u],v;i;i=G[i].next){
v = G[i].to;if(v == fa[u]) continue;
fa[v] = u;dfs(v);
g[u] ^= (g[v] + 1);
}
}
int main(){
int n;read(n);
int u,v;
rep(i,2,n){
read(u);read(v);
add(u,v);add(v,u);
}dfs(1);
puts(g[1] == 0 ? "Bob" : "Alice");
return 0;
}
E - Jigsaw
题目:
叙述不清,自己看题.
\(link\space to\space Atcoder\)
题解:
很容易想到接口什么的。
每个物品实际上都有两个接口。
考虑都没一段物品两端一定都是落地的。
我们考虑让所有左端落地的左端接口参数为正。反之为负。
所有右端落地的右端接口参数为负,反之为正。
我们发现所有右端接口参数等于左端接口参数的两个物品可以拼接。
考虑转化模型:
抽象出 \(2H\) 个点 \(-H,-(H-1), ... , -1 , 1 , 2 , ... ,H\)
那么对于我们物品设左端接口参数为 \(u\) 右端接口参数为 \(v\).
我们就连接一条 \((u,v)\) 的边。
那么现在的问题就是是否能够将所有的边拆分成若干条路径并且边不重复使用。
使得所有的路径都是从正数节点开始,负数节点结束。
对于这个判断,我们直接判断一下:
- 所有正数节点是否都满足 \(出度 \geq 入度\)
- 所有负数节点是否都满足 \(入读 \geq 出度\)
- 所有弱连通分量中至少存在一个满足 \(出度 \neq 入读\) 的点
如果都满足那么可行。
不难发现这样是对的。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;static char ch;static bool flag;flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 512;
const int zero = 250;
int fa[maxn],siz[maxn],oud[maxn],ind[maxn];bool h[maxn];
int find(int x){return fa[x] == x ? x : fa[x] = find(fa[x]);}
inline void Union(int x,int y){
x = find(x);y = find(y);
if(x == y) {++siz[x];return ;}
fa[x] = y;siz[y] += siz[x] + 1;
}
int main(){
int n,H;read(n);read(H);
rep(i,1,H) fa[i+zero] = i+zero,siz[i+zero] = 1;
rep(i,-H,-1)fa[i+zero] = i+zero,siz[i+zero] = 1;
int a,b,c,d;
rep(i,1,n){
int x,y;
read(a);read(b);read(c);read(d);
if(c == 0) x = a;else x = -c;
if(d == 0) y = -b;else y = d;
++ oud[x + zero];++ ind[y + zero];
Union(x+zero,y+zero);
}
rep(i,1,H) if(oud[i+zero] < ind[i+zero]) return puts("NO"),0;
rep(i,-H,-1)if(ind[i+zero] < oud[i+zero]) return puts("NO"),0;
rep(i,1,H) h[find(i+zero)] |= (ind[i+zero]!=oud[i+zero]);
rep(i,-H,-1)h[find(i+zero)] |= (ind[i+zero]!=oud[i+zero]);
rep(i,1,H) if(siz[find(i+zero)] > 1 && (find(i+zero) == i+zero) && (h[i+zero] == false)) return puts("NO"),0;
rep(i,-H,-1)if(siz[find(i+zero)] > 1 && (find(i+zero) == i+zero) && (h[i+zero] == false)) return puts("NO"),0;
puts("YES");
return 0;
}
AtCoder Grand Contest 017 题解的更多相关文章
- AtCoder Grand Contest 017题解
传送门 \(A\) 直接转移就是了 typedef long long ll; const int N=55; ll f[N][2];int a[N],n,p; int main(){ scanf(& ...
- 题解——ATCoder AtCoder Grand Contest 017 B - Moderate Differences(数学,构造)
题面 B - Moderate Differences Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Stat ...
- AtCoder Grand Contest 017 F - Zigzag
题目传送门:https://agc017.contest.atcoder.jp/tasks/agc017_f 题目大意: 找出\(m\)个长度为\(n\)的二进制数,定义两个二进制数的大小关系如下:若 ...
- AtCoder Grand Contest 017 (VP)
contest link Official Editorial 比赛体验--之前做题的时候感觉 AtCoder 挺快的,现在打了VP之后发现还是会挂的--而且不是加载缓慢或者载不出来,直接给你一个无法 ...
- Atcoder Grand Contest 054 题解
那天晚上由于毕业晚会与同学吃饭喝酒没打 AGC,第二天稍微补了下题,目前补到了 E,显然 AGC 的 F 对于我来说都是不可做题就没补了(bushi A 简单题,不难发现如果我们通过三次及以上的操作将 ...
- AtCoder Grand Contest 017
noi前橙名计划失败.全程搞C而gg…… A - Biscuits 题意:背包,求价值为奇/偶的方案数. #include<cstdio> #include<queue> #i ...
- AtCoder Grand Contest 030题解
第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...
- AtCoder Grand Contest 031题解
题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...
- AtCoder Grand Contest 017 迟到记
晚上去操场上浪. 回来以后看到好几个人开着 \(AtCoder\) 在打代码. ... ... 今天有 \(AtCoder\) 比赛 ? 管它呢, \(Kito\) 在切西瓜,先吃西瓜... 然后看 ...
随机推荐
- Android应用程序用真机调试步骤
仅供参考: 1.开启调试模式 2.安装 Adb.exe 将platform-tools文件夹里面adb.exe AdbWinApi.dll AdbWinUsbApi.dll拷贝到tools ...
- 并查集 试水 hdu1232
#include <stdio.h> #include <stdlib.h> int n,m; ],rank[]; int count; int find(int x) { i ...
- Linux下Wireshark的网络抓包使用方法
Wireshark是世界上最流行的网络分析工具.这个强大的工具可以捕捉网络中的数据,并为用户提供关于网络和上层协议的各种信息.与很多其他网络工具一样,Wireshark也使用pcap network ...
- 近千节点的Redis Cluster高可用集群案例:优酷蓝鲸优化实战(摘自高可用架构)
(原创)2016-07-26 吴建超 高可用架构导读:Redis Cluster 作者建议的最大集群规模 1,000 节点,目前优酷在蓝鲸项目中管理了超过 700 台节点,积累了 Redis Clus ...
- spring security采用自定义登录页和退出功能
更新... 首先采用的是XML配置方式,请先查看 初识Spring security-添加security 在之前的示例中进行代码修改 项目结构如下: 一.修改spring-security.xml ...
- MySQL主从配置实现
//////////////////////MySQL主从配置//////////////////////////// 首先,两边都要安装MySQL,启动两边的MySQL 接着,配置主从,要保证主从数 ...
- Maven添加Oracle驱动及依赖
oracle驱动先去官网下载,下载下来后,需要安装到maven本地仓库,然后再pom中添加依赖. 1下载oracle驱动包 ojdbc6-11.2.0.3.jar 2命令行安装到maven仓库 mvn ...
- PHP的可变变量名
有时候可变的变量名会给编程带来很大的方便.也就是说变量名可以被动态的命名和使用.通常变量通过下面这样的语句来命名 : 1 2 3 <!--?php $a = 'hello'; ?--> 可 ...
- 关于有时候Servlet会被执行两次的问题
用<a>标签做了下载跳转,为什么点一次,servlet会被执行两次? 写了一个最简单的文件下载 点击超链接向servlet发送一个请求,然后下载该文件.可是每次该servlet都会被访问两 ...
- 手把手教你用Vue2+webpack+node开发一个H5 app
手把手教你用Vue2+webpack+node开发一个H5 app 前一篇vue2 + webpack + node 开发一个小demo说到了用vue的一些基本用法,这一篇就讲一个复杂一点的更完整的 ...