【CodeChef】December Challenge 2019 Div1 解题报告
这次比赛本来想好好打的,但不幸的是,这周先是要认真复习准备月考,考完又是发烧在床上躺了一个周末,所以最终没能打完。
我还是好弱啊。
\(T1\):Binary XOR(点此看题面)
大致题意: 给定两个长度为\(n\)的\(01\)串,你能任意打乱两个字符串中的字符顺序,求所能得到的异或值个数。
设第一个字符串中有\(t1\)个\(1\),第二个字符串中有\(t2\)个\(1\)。
我们枚举有恰好\(i\)位满足两个字符串该位都是\(1\),则异或所得串中就有\(t1+t2-2\times i\)位是\(1\)。
则此时有\(i+t1+t2-2\times i=t1+t2-i\)位是已占用的。
因此\(i\)显然要满足:\(t1+t2-i\le n\)且\(0\le i\le min(t1,t2)\)。
则对于每一个合法的\(i\),我们都可以将答案加上\(C_n^{t1+t2-2\times i}\)。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define X 1000000007
#define C(x,y) (1LL*Fac[x]*IFac[y]%X*IFac[(x)-(y)]%X)//组合数
using namespace std;
int n,Fac[N+5],IFac[N+5];char s[N+5];
I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
int main()
{
RI i;for(Fac[0]=i=1;i<=N;++i) Fac[i]=1LL*Fac[i-1]*i%X;//预处理阶乘
for(IFac[N]=Qpow(Fac[N],X-2),i=N-1;~i;--i) IFac[i]=1LL*IFac[i+1]*(i+1)%X;//预处理阶乘逆元
RI Tt,t1,t2,ans;scanf("%d",&Tt);W(Tt--)
{
scanf("%d",&n),t1=t2=ans=0;//初始化清空
for(scanf("%s",s+1),i=1;i<=n;++i) t1+=s[i]&1;for(scanf("%s",s+1),i=1;i<=n;++i) t2+=s[i]&1;//统计两个串中1的个数
for(i=0;t1+t2-i>n;++i);for(;i<=min(t1,t2);++i) ans=(C(n,t1+t2-2*i)+ans)%X;//枚举i,统计答案
printf("%d\n",ans);
}return 0;
}
\(T2\):Addition(点此看题面)
大致题意: 给定两个数\(A,B\),问将会执行下述函数中的循环多少次:
function add(A, B):
while B is greater than 0:
U = A XOR B
V = A AND B
A = U
B = V * 2
return A
考虑两个数二进制下的同一位,若满足:
- 皆为\(1\):在\(V\)中这一位会是\(1\),则新的\(B\)中这位的左一位将会变成\(1\)。
- 一个为\(0\),一个为\(1\):在\(U\)(\(A\))中这一位会是\(1\)。
因此我们可以发现,初始状态下,对于每个\(A,B\)该位上都为\(1\)的一位,设它的向左\(t\)位首次不满足\(A,B\)中一个为\(0\)、一个为\(1\),要想把这一位消干净,就需要循环\(t+1\)次(可以自己举例验证,这里偷懒了)。
注意,找到向左\(t\)位后,可以直接从这一位继续操作, 所以时间复杂度是\(O(n)\)的。
还有,由于一开始两个数的位数不一定相同,注意先补齐。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
using namespace std;
int n,m;char s1[N+5],s2[N+5];
int main()
{
RI Tt,i,j,p,t;scanf("%d",&Tt);W(Tt--)
{
scanf("%s",s1+1),scanf("%s",s2+1),n=strlen(s1+1),m=strlen(s2+1);
if(m==1&&s2[1]==48) {puts("0");continue;}//特判B=0
if(n<m) {for(i=1;i<=n;++i) s1[m-i+1]=s1[n-i+1];for(i=1;i<=m-n;++i) s1[i]=48;n=m;}//补齐
else {for(i=1;i<=m;++i) s2[n-i+1]=s2[m-i+1];for(i=1;i<=n-m;++i) s2[i]=48;m=n;}//补齐
for(p=min(n,m),t=1,i=n;i;--i) if(s1[i]==49&&s2[i]==49)//枚举某一位两个字符串都为1
{j=i-1;W(j&&s1[j]+s2[j]==97) --j;t<(i-j+1)&&(t=i-j+1),i=j+1;}//找到向左首个不满足条件的位置,更新答案,并从该位继续扫描
printf("%d\n",t);
}return 0;
}
\(T3\):Chefina and Ranges(点此看题面)
大致题意: 给定若干区间,求至少删去多少区间,才可以把所有区间分成两个集合,使得所有相交的区间分在同一集合中。
考虑可以枚举一个分界点\(i\),使得分界点左边所有区间右端点\(\le i\),分界点右边所有区间左端点\(>i\),并且满足分界点左、右都满足存在至少一个完整区间。
通过上面的限制,我们可以发现,\(i\)其实就是从所有区间中最小的右端点,一直枚举到所有区间中最大的左端点减\(1\)。
而对于每一个分界点,要删去的区间个数就是跨过这个分界点的区间个数。
这可以直接差分+前缀和求。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
using namespace std;
int n,dc,x[N+5],y[N+5],s[2*N+5],dv[2*N+5];
int main()
{
RI Tt,i,l,r,t;scanf("%d",&Tt);W(Tt--)
{
for(l=1e9,r=0,scanf("%d",&n),i=1;i<=n;++i) scanf("%d%d",x+i,y+i),
l>y[i]&&(l=y[i]),r<x[i]&&(r=x[i]),dv[2*i-1]=x[i],dv[2*i]=y[i];
if(l>r-1) {puts("-1");continue;}//所有区间有交集,判无解
for(sort(dv+1,dv+2*n+1),dc=unique(dv+1,dv+2*n+1)-dv-1,i=1;i<=dc;++i) s[i]=0;//离散化
#define GV(x) (lower_bound(dv+1,dv+dc+1,x)-dv)
for(i=1;i<=n;++i) ++s[GV(x[i])],--s[GV(y[i])];for(i=1;i<=dc;++i) s[i]+=s[i-1];//差分+前缀和
for(t=n,i=GV(l),r=GV(r);i^r;++i) t>s[i]&&(t=s[i]);printf("%d\n",t);//枚举分界点,计算答案
}return 0;
}
\(T4\):Sticky Notes(点此看题面)
大致题意: 给定一棵树,可以免费交换点权和边权,或者花费\(1\)的代价把某个点权改成任意值,求最小代价使得所有点的点权大于等于与其相连边的边权。
考虑要修改某个点权,一定贪心地把它改成\(INF\)。
假设我们完成了修改,然后将点权\(a_{1\sim n}\)和边权\(b_{1\sim n-1}\)从小到大排序,当且仅当满足\(1\le i\le n-1\)的每一个\(a_i\ge b_i\),此时存在一种构造方式符合题目要求。
这可以自己考虑证明,应该还是比较简单的,这里懒得证了。
考虑接下来怎么做,其实就是将\(a\)和\(b\)分别排序,方便起见让\(b_n=b_{n-1}\)。
枚举\(a_i\),记录当前\(b\)数组中匹配到第\(j\)个,已经花费了\(t\)的代价。
如果\(a_i\ge b_j\),那么将\(j\)加\(1\),否则说明必须要花费\(1\)的代价将\(a_i\)修改成\(INF\),因此将\(t\)加\(1\)。
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
using namespace std;
int n,a[N+5],b[N+5];
int main()
{
RI Tt,i,j,t;scanf("%d",&Tt);W(Tt--)
{
for(scanf("%d",&n),i=1;i^n;++i) scanf("%d%d%d",&t,&t,b+i);
for(i=1;i<=n;++i) scanf("%d",a+i);sort(a+1,a+n+1),sort(b+1,b+n);//排序
for(b[n]=b[n-1],t=0,i=j=1;i<=n;++i) a[i]>=b[j]?++j:++t;printf("%d\n",t);//枚举,计算并输出答案
}return 0;
}
\(T5\):Test Generation(占坑待填)
\(T6\):(Challenge) Cubical Virus(占坑待填)
\(T7\):Scoring Pairs(题解待补)
\(T8\):Binomial Fever(占坑待填)
【CodeChef】December Challenge 2019 Div1 解题报告的更多相关文章
- 【CodeChef】August Challenge 2019 Div2 解题报告
点此进入比赛 \(T1\):Football(点此看题面) 大致题意: 求\(max(20a_i-10b_i,0)\). 送分题不解释. #include<bits/stdc++.h> # ...
- Codechef April Challenge 2019 游记
Codechef April Challenge 2019 游记 Subtree Removal 题目大意: 一棵\(n(n\le10^5)\)个结点的有根树,每个结点有一个权值\(w_i(|w_i\ ...
- Codechef August Challenge 2019 Division 2
Preface 老年菜鸡终于开始打CC了,由于他太弱了所以只能打Div2 因为台风的原因challenge并没有写,所以水了个Rank7 A Football SB模拟题不解释 #include< ...
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries
https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef and Hamming Distance of arrays
https://www.codechef.com/DEC17/problems/CHEFHAM #include<cstdio> #include<cstring> #incl ...
- CF&&CC百套计划2 CodeChef December Challenge 2017 Total Diamonds
https://www.codechef.com/DEC17/problems/VK18 #include<cstdio> #include<iostream> #includ ...
- CF&&CC百套计划2 CodeChef December Challenge 2017 Penalty Shoot-out
https://www.codechef.com/DEC17/problems/CPLAY #include<cstdio> #include<algorithm> using ...
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And his Cake
https://www.codechef.com/DEC17/problems/GIT01 #include<cstdio> #include<algorithm> using ...
- CodeChef April Challenge 2019题解
传送门 \(Maximum\ Remaining\) 对于两个数\(a,b\),如果\(a=b\)没贡献,所以不妨假设\(a<b\),有\(a\%b=a\),而\(b\%a<a\).综上, ...
随机推荐
- 更新阿里yum源并重建缓存
[第一种方式]1.下载安装wget /如果没有装的话yum install -y wget 2.备份默认的yummv /etc/yum.repos.d /etc/yum.repos.d.backup ...
- windows 下 安装vue环境 以及创建新项目 极简
一.安装node.js(https://nodejs.org/en/) 官网下载安装 验证命令: node -v 二.安装npm npm install -g cnpm --registry=http ...
- leetcode-10
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符'*' 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串 s的 ...
- Cisdem OCRWizard for Mac 使用教程
Cisdem OCRWizard for Mac是一款macOS平台的的文件识别软件,可以对任何PDF.扫描文件或图像文件(包括名片的照片)进行OCR识别,支持超过40种语言,帮助我们提高效率.现在小 ...
- CSS新特性之3D转换
1. 三维坐标系 x轴:水平向右(右边是正,左边是负) y轴:垂直向下(向下是正,向上是负) z轴:垂直屏幕(向外是正,向里是负) 2. 3D转换 3D转换中最常用的是3D位移和3D旋转.主要知识点如 ...
- pwn-200
题目连接 https://adworld.xctf.org.cn/media/task/attachments/49bd95c78386423997fa044a9e750015 借鉴 https:// ...
- 开发一个这样的 APP 要多长时间?
作者:蒋国刚 www.cnblogs.com/guogangj/p/4676836.html 这是一个“如有雷同,纯属巧合”的故事,外加一些废话,大家请勿对号入座.开始了…… 我有些尴尬地拿着水杯,正 ...
- strlen函数 (求字符串长度函数)
strlen函数原型在<string.h>中 #include <stdio.h> #include <string.h> int main(){ char *p= ...
- .net core 反射的介绍与使用
1. 概述反射 通过反射可以提供类型信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象. 反射机制允许程序在执行过程中动态地添加各种功能. 2. Type类的介绍 是BCL(基 ...
- Python爬虫,你是否真的了解它?
程序员有时候很难和外行人讲明白自己的工作是什么,甚至有些时候,跟同行的人讲清楚“你是干什么的”也很困难.比如我自己,就对Daivd在搞的语义网一头雾水.所以我打算写一篇博客,讲一下“爬虫工程师”的工作 ...