Preface

又自己开了场CF/Atcoder杂题,比昨天的稍难,题目也更有趣了

昨晚炉石检验血统果然是非洲人...

希望这是给NOIP2018续点rp吧

A.CF1068C-Colored Rooks

现在还没理解题意...

B. CF1070K-VideoPosts

一道模拟,没什么好说的.

不过一开始还是WA了...一个智障的坑,感觉做题还是不细心

const int maxn=100005;
const int inf=0x7fffffff;
int a[maxn],ave,n,k,cnt=0;
int ans[maxn],tot=0;
ll sum=0;
int main(){
read(n),read(k);
for(ri i=1;i<=n;i++){
read(a[i]);
sum+=a[i];
}
if(sum%k!=0){
puts("No");
return 0;
}
ave=sum/k;
sum=0;
for(ri i=1;i<=n;i++){
sum+=a[i],cnt++;
if(sum==ave){
ans[++tot]=cnt;//printf("%d ",cnt);
sum=cnt=0;
}
else if(sum>ave){
puts("No");
return 0;
}
}
puts("Yes");
for(ri i=1;i<=tot;i++)printf("%d ",ans[i]);
puts("");
return 0;
}

C. CF1036D-VasyaAndArrays

一看就是一道贪心题,很多人都会猜测就是两个指针不断拓展,如果两个数相等就不加.

想了想发现似乎是正确的,但是不会严格证明,交了发居然A了

const int maxn=300005;
const int inf=0x7fffffff;
int n,m;
int a[maxn],b[maxn];
ll sum1=0,sum2=0;
int main(){
read(n);
for(ri i=1;i<=n;i++)read(a[i]),sum1+=a[i];
read(m);
for(ri i=1;i<=m;i++)read(b[i]),sum2+=b[i];
if(sum1!=sum2){
puts("-1");
return 0;
}
int len=0,pos1=1,pos2=1;
sum1=a[1],sum2=b[1];
while(1){
while(sum1!=sum2){
if(sum1>sum2)sum2+=b[++pos2];
else sum1+=a[++pos1];
}
len++;
if(pos1==n&&pos2==m)break;
sum1=a[++pos1],sum2=b[++pos2];
}
printf("%d\n",len);
return 0;
}

D. CF1038D-Slime

非常有意思的题,一开始想区间DP,但是发现好像是有后效性的,交了发果然WA了

然后只能往贪心这方面想

偶然发现样例非常有意思,一个全正数, 一个全负数+0.

易知如果全是正数的话就可以贪心,你用最小的史莱姆吃掉出最大值以外的所有数,然后最大值吃掉这个数肯定是最优的.这样子答案就是sum-mi-mi

如果是全负数加上一个0,我们就是用0吃掉所有负数显然是最优的

那如果既有非负数又有负数,我们可以用负数减去除最大值以外所有非负整数,然后最大值吃掉所有负数就是最优的,这样子就是所有元素之和

但是如果全都是负数按照全都是正数的思路就是sum-mx-mx

const int maxn=500005;
const int inf=1e9;
int n,a[maxn],mi=inf,mx=-inf;
int main(){
bool flag=0,flag_2=0;
ll sum=0;
read(n);
if(n==1){
read(a[1]);
printf("%d\n",a[1]);
return 0;
}
for(ri i=1;i<=n;i++){
read(a[i]);
mi=min(a[i],mi);
mx=max(a[i],mx);
sum+=abs(a[i]);
if(a[i]<0)flag=1;
if(a[i]>=0)flag_2=1;
}
if(flag){
if(flag_2)printf("%lld\n",sum);
else printf("%lld\n",sum+mx*2);
}
else {
printf("%lld\n",sum-mi*2);
}
return 0;
}

E. Atcoder4167-Equal Cut

一道ARC的B题就不会做了,太菜了...

感觉solution很妙啊,枚举中间的断点.这时候分成了L,R两部分,显然我们还要把L,R分成L1,L2和R1,R2两部分

这时候有一个结论就是让abs(L1-L2)和abs(R1-R2)尽量小一定是最优方案,这个还是比较显然的

这时候可以发现我们在枚举中间断点的时候分割L1,L2的断点和分割R1,R2的断点都是单调的

这里的断点是指abs(L1-L2)和abs(R1-R2)尽量小的断点

于是我们就可以\(O(N)\)扫一遍得出答案了

同时发现一个很坑的地方:

std::abs()而不是abs(),因为差点没查出错来

const int maxn=1000005;
const int inf=0x7fffff;
int n;
ll a[maxn];
ll sum[maxn],mi=1e18,mx=-1e18,ans=1e18,tmp;
int main(){
int x,y;
read(n);
sum[0]=0;
for(ri i=1;i<=n;i++)read(a[i]),sum[i]=sum[i-1]+a[i];
int l=1,r=3;
for(ri k=2;k<=n-2;k++){
while((abs((sum[k]-sum[l+1])-(sum[l+1]))<abs(sum[k]-sum[l]-sum[l]))&&l+1<k)l++;
while((abs((sum[n]-sum[r+1])-(sum[r+1]-sum[k]))<abs((sum[n]-sum[r])-(sum[r]-sum[k])))&&r+1<n)r++;
mi=1e18,mx=-1e18;
tmp=sum[k]-sum[l];
mi=min(mi,tmp),mx=max(mx,tmp);
tmp=sum[l];
mi=min(mi,tmp),mx=max(mx,tmp);
tmp=sum[n]-sum[r];
mi=min(mi,tmp),mx=max(mx,tmp);
tmp=sum[r]-sum[k];
mi=min(mi,tmp),mx=max(mx,tmp);
ans=min(ans,mx-mi);
}
printf("%lld\n",ans);
return 0;
}

F. Atcoder4351-Median Of Medians

这题考试的时候也不会做,考试后发现正解简直太妙了

首先我们需要知道一个性质:如果\(x\)是一个长度为\(N\)的序列的中位数,那么小于等于x的数的个数至少有\(N/2+1\)个

于是我们不妨二分一下最后的中位数是哪个,然后我们只需要知道有多少个区间的中位数是小于等于我们二分的这个数就可以了

这里就需要一个高端操作:我们将原序列中小于等于这个数的数置为1,否则置为-1;这样操作之后可以发现如果一个区间的中位数小于等于x,那么这个区间之和肯定大于0.所以我们转化成有多少个区间之和大于0.

我们对这个新序列求一遍前缀和,我们都知道区间\([L,R]\)的和等于\(sum[R]-sum[L-1]\),如果想要这个区间和大于0,实际上就是\(sum[R]>sum[L-1]\),又由于\(R>L-1\),那么我们发现区间之和大于0的区间个数实际上就是新序列前缀和后的顺序对个数,我们离散化之后按照逆序对套路处理即可

但是注意这时候我们没有计算类似\([1,R]\)的区间,这个直接记录一下就好了

但是回到前面的话题,我们已经知道了有多少个区间的中位数小于等于当前二分的这个数,我们该如何更改这个二分边界呢?

还是一开始那个性质,由于区间个数总共有\(N \times (N+1)/2\)个,所以大于等于二分的这个数的区间个数如果大于等于\(N \times (N+1)/4+1\)的话,则将二分右边界左移,否则左边界右移

注意一开始\(N \times (N+1)\) 前没打1ll,结果爆int了,查了好久的错...

const int maxn=200005;
const int inf=0x7fffffff;
int n,nn,a[maxn],b[maxn],c[maxn],mx=-inf,mi=inf;
ll sum[maxn<<2];
inline void update(int x,int d){for(;x<=nn;x+=x&(-x))sum[x]+=d;}
inline ll query(int x){ll ans=0;for(;x;x-=x&(-x))ans+=sum[x];return ans;}
inline ll chk(int k){
ll ans=0;
b[0]=0;
for(ri i=1;i<=n;i++){
b[i]=b[i-1]+((a[i]<=k)?1:-1);
c[i]=b[i];
ans+=(b[i]>0);//记录[1,R]的区间
}
std::sort(c+1,c+1+n);
nn=std::unique(c+1,c+1+n)-(c+1);
memset(sum,0,sizeof(sum));
for(ri i=1;i<=n;i++){
b[i]=lower_bound(c+1,c+1+nn,b[i])-c;//离散化
ans+=query(b[i]-1);
update(b[i],1);
}
return ans;
}
int main(){
read(n);
for(ri i=1;i<=n;i++){
read(a[i]);
mi=min(mi,a[i]),mx=max(mx,a[i]);
}
int L=mi,R=mx,mid,ans;
ll lim=1ll*n*(n+1)/4+1;
while(L<=R){
mid=(L+R)>>1;
if(chk(mid)>=lim)ans=mid,R=mid-1;
else L=mid+1;
}
printf("%d\n",ans);
return 0;
}

Atcoder&CodeForces杂题11.7的更多相关文章

  1. Atcoder&CodeForces杂题11.6

    Preface NOIP前突然不知道做什么,感觉思维有点江僵化,就在vjudge上随便组了6道ABC D+CF Div2 C/D做,发现比赛质量还不错,知识点涉及广,难度有梯度,码量稍小,思维较多. ...

  2. Codeforces 杂题集 2.0

      记录一些没有写在其他随笔中的 Codeforces 杂题, 以 Problemset 题号排序   1326D2 - Prefix-Suffix Palindrome (Hard version) ...

  3. AtCoder,Codeforces做题记录

    AGC024(5.20) 总结:猜结论,“可行即最优” B: 给定一个n的排列,每次可以将一个数移到开头或结尾,求变成1,2,...,n所需的最小步数. 找到一个最长的i,i+1,...,j满足在排列 ...

  4. Codeforces Global Round 11 个人题解(B题)

    Codeforces Global Round 11 1427A. Avoiding Zero 题目链接:click here 待补 1427B. Chess Cheater 题目链接:click h ...

  5. 贪心/构造/DP 杂题选做Ⅲ

    颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...

  6. 贪心/构造/DP 杂题选做Ⅱ

    由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...

  7. Codeforces刷题计划

    Codeforces刷题计划 已完成:-- / -- [Codeforces370E]370E - Summer Reading:构造:(给定某些数,在空白处填数,要求不下降,并且相邻差值<=1 ...

  8. Codeforces Beta Round #11 B. Jumping Jack 数学

    B. Jumping Jack 题目连接: http://www.codeforces.com/contest/11/problem/B Description Jack is working on ...

  9. Codeforces Beta Round #11 A. Increasing Sequence 贪心

    A. Increasing Sequence 题目连接: http://www.codeforces.com/contest/11/problem/A Description A sequence a ...

随机推荐

  1. Kali Linux又增加一个顶级域名kali.download

    Kali Linux又增加一个顶级域名kali.download 现阶段,kali.download只提供软件包和镜像下载.大家可以把该域名作为备选软件源来使用.形式如下: deb  http://k ...

  2. Leetcode: Campus Bikes II

    On a campus represented as a 2D grid, there are N workers and M bikes, with N <= M. Each worker a ...

  3. Mac 打开、编辑 .bash_profile 文件

    export PATH=${PATH}:/Users/loaderman/Library/Android/sdk/platform-tools export PATH=${PATH}:/Users/l ...

  4. shell编程系列26--大型脚本工具开发实战

    shell编程系列26--大型脚本工具开发实战 大型脚本工具开发实战 拆分脚本功能,抽象函数 .function get_all_group 返回进程组列表字符串 .function get_all_ ...

  5. C++ 11 线程调用类的成员函数解决办法

    在C++中,_beginthreadex 创建线程是很麻烦的.要求入口函数必须是类的静态函数. 通常,可以采用thunk,或者模板来实现. 因C++ 11中引入了 std::async ,可以很好的解 ...

  6. linux普通用户添加root权限

    新增一个普通用户并进入该用户: [root@VM_0_7_centos ~]# groupadd mall [root@VM_0_7_centos ~]# useradd mall -m -d /ho ...

  7. windows下新增项目本地通过git bash推送至远程github

    本地E盘workspace目录下新增了spring-cloud-alibaba-demo项目,还没有编译过,没有target等不需要推送至git的文件,所以就直接用git bash丢到github了. ...

  8. 泡泡一分钟:Fast and Robust Initialization for Visual-Inertial SLAM

    张宁  Fast and Robust Initialization for Visual-Inertial SLAM链接:https://pan.baidu.com/s/1cdkuHdkSi9x7l ...

  9. 【DataBase】H2 DateBase与项目集成

    本例介绍H2与web项目的集成 项目启动H2数据库 1.新建Maven Web项目,参考:[Maven]Eclipse 使用Maven创建Java Web项目 2.引入h2的jar包依赖 <de ...

  10. PhpStorm的主题和字体设置

    打开PhpStorm,点击File,然后点击Setting 然后 点击Apply,就可以看到主题变化的效果,其次就是来设置字体,先要选取一个样式,然后点击Save As ,然后命名,我选择的是最后一个 ...