https://codeforces.com/contest/1363

A. Odd Selection

第一反应当然是分类讨论if到底。想了一下发现好像有点麻烦,正好n又不大所以for一下

枚举的方法,枚举原数组中取多少偶数(记为i),那么原数组中奇数就要取x-i个,只要判断x-i是否为奇数并且原数组的奇数个数是否大于等于x-i就行了

分类讨论的方法,难顶,详见代码

枚举的代码

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll;
#define int ll
int T,n,x,a[2],t;
void output(bool x){cout<<(x?"Yes":"No")<<endl;}
signed main(){
cin>>T;
while(T--){
cin>>n>>x;
a[0]=a[1]=0;
int f=0;
repeat(i,0,n)cin>>t,a[t%2]++;
repeat(i,0,a[0]+1){
if((x-i)%2==1 && a[1]>=x-i){
output(1);
f=1;
break;
}
}
if(!f)output(0);
}
return 0;
}

分类讨论的代码(转载自 %%%施老师)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int T,n,k,x,num1,num2;
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&k); num1=0; num2=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
if (x&1) num1++;else num2++;
}
if (num1==0) printf("No\n");
else
{
num1--; k--; k-=2*min(num1/2,k/2);
if (k<=num2) printf("Yes\n");else printf("No\n");
}
}
return 0;
}

B. Subsequence Hate

显而易见,s最终只有两种情况,00..0011..11和11..1100..00。我们枚举一下01分界线。为了加点速,要用前缀和记录前x个位置有多少1,这样 \(O(1)\) 询问答案,美滋滋

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll;
#define int ll
int T,n,sum[N];
string s;
int q1(int l,int r){ //询问[l,r]有多少个1
return sum[r]-sum[l-1];
}
int q0(int l,int r){ //询问[l,r]有多少个0
return r-l+1-q1(l,r);
}
signed main(){
cin>>T;
while(T--){
cin>>s; s='x'+s;
int n=s.size()-1;
repeat(i,1,n+1)
sum[i]=sum[i-1]+(s[i]=='1');
int ans=1e9;
repeat(i,0,n+1){ //枚举分界线
ans=min(ans,q0(1,i)+q1(i+1,n));
ans=min(ans,q1(1,i)+q0(i+1,n));
}
cout<<ans<<endl;
}
return 0;
}

C. Game On Leaves

一般来说,双方都会尽量不让x节点的度变成小于等于1,因此这个x节点大多情况都是倒数第二个取走的。除了x节点的度已经小于等于1了

所以只要判断x节点的度是否小于等于1,再判断n的奇偶性就行了

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll;
#define int ll
int T,n,x;
signed main(){
cin>>T;
while(T--){
cin>>n>>x;
int deg=0;
repeat(i,0,n-1){
int u,v; cin>>u>>v;
if(u==x || v==x)deg++;
}
if(deg<=1 || n%2==0)cout<<"Ayush"<<endl;
else cout<<"Ashish"<<endl;
}
return 0;
}

D. Guess The Maximums

如果你觉得数组A遍历了[1,n],或者Si遍历了[1,n],或者两个地雷一起踩(正是在下),那就有可能fst惨案(没考虑数组A的最大值不一定是n的话,会wa41,这已经不是pretest了qwq)

先询问一下数组A中的最大值,记为maxx。因为只有包含了A中所有的maxx的集合,其补集的最大值才不是maxx,因此,其他集合的答案已经确定为maxx了,我们只要找到这个神奇的集合,然后询问这个集合的补集作为这个集合的答案,这题就完成了

而找这个神奇的集合,只要二分查找就行了。注意因为询问次数卡得很紧,千万不要有多余的询问。比如之前我询问了神奇集合是否包含maxx,如果包含了再询问这个集合的补集,实际上第一个询问不是必要的,因为询问任一集合的补集都是这个集合的答案

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=1010; typedef long long ll;
int T,n,k;
vector<int> a[N]; //存第i个集合的内容
vector<int> q; //存放询问内容
int ans[N]; //存放最终答案
string s;
int query(){ //询问
cout<<"? "<<q.size()<<' ';
for(auto i:q)cout<<i<<' '; cout<<endl;
cout.flush();
int ans; cin>>ans; if(ans==-1)exit(233);
return ans;
}
void pushquery(int l,int r){ //讲一个区间的集合的内容存入q中
repeat(i,l,r+1)
for(auto j:a[i])
q.push_back(j);
}
void output(){ //输出最终答案
cout<<"! ";
repeat(i,1,k+1)cout<<ans[i]<<' '; cout<<endl;
cout.flush();
cin>>s; if(s[0]=='I')exit(234);
}
signed main(){
cin>>T;
while(T--){
cin>>n>>k;
repeat(i,1,k+1){
int c; cin>>c;
a[i].clear();
while(c--){
int x; cin>>x;
a[i].push_back(x);
}
}
int l=1,r=k; q.clear();
repeat(i,1,n+1)q.push_back(i);
int maxx=query(); //询问max(Ai)
fill(ans+1,ans+k+1,maxx); while(l<r){ //二分查找可能包含maxx的集合
int m=(l+r)/2;
q.clear(); pushquery(l,m);
if(query()!=maxx)l=m+1;
else r=m;
}
int t=l; //此时St可能包含maxx sort(a[t].begin(),a[t].end());
q.clear();
repeat(i,1,n+1){
if(!binary_search(a[t].begin(),a[t].end(),i))
q.push_back(i);
}
ans[t]=query(); //询问St的补集,作为ans[t]的答案(唯一可能不是maxx的答案)
output();
}
return 0;
}

E. Tree Shuffling

树型dp

我们让儿子的费用(即 \(a[i]\))赋值为\(\min\)(儿子费用,父亲费用),这样操作的好处是,如果儿子所在的子树存在需要互换的两个节点,那一定是儿子解决这个问题而不是去麻烦父亲乃至祖宗

因此只要统计每个子树的需要把0变1的节点个数,以及1变0的节点个数,然后及时计算费用,然后把这两个值传给父亲即可

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll;
#define int ll
int n,x;
vector<int> a[N];
int cost[N],b[N],c[N],ans,cnt[N][2];
void dfs(int x,int fa){
if(fa!=-1)cost[x]=min(cost[x],cost[fa]);
for(auto p:a[x])
if(p!=fa){
dfs(p,x);
cnt[x][0]+=cnt[p][0];
cnt[x][1]+=cnt[p][1];
}
if(b[x]!=c[x])cnt[x][b[x]]++;
int t=min(cnt[x][0],cnt[x][1]);
ans+=2*t*cost[x];
cnt[x][0]-=t;
cnt[x][1]-=t;
}
signed main(){
cin>>n;
repeat(i,0,n)cin>>cost[i]>>b[i]>>c[i];
repeat(i,0,n-1){
int x,y; cin>>x>>y; x--,y--;
a[x].push_back(y);
a[y].push_back(x);
}
dfs(0,-1);
if(cnt[0][0] || cnt[0][1])cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}

Codeforces Round #646 (Div. 2) 题解 (ABCDE)的更多相关文章

  1. Codeforces Round #643 (Div. 2) 题解 (ABCDE)

    目录 A. Sequence with Digits B. Young Explorers C. Count Triangles D. Game With Array E. Restorer Dist ...

  2. Codeforces Round #182 (Div. 1)题解【ABCD】

    Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...

  3. Codeforces Round #608 (Div. 2) 题解

    目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...

  4. Codeforces Round #525 (Div. 2)题解

    Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...

  5. Codeforces Round #528 (Div. 2)题解

    Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...

  6. Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F

    Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...

  7. Codeforces Round #677 (Div. 3) 题解

    Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...

  8. Codeforces Round #665 (Div. 2) 题解

    Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...

  9. Codeforces Round #383 (Div. 2) 题解【ABCDE】

    Codeforces Round #383 (Div. 2) A. Arpa's hard exam and Mehrdad's naive cheat 题意 求1378^n mod 10 题解 直接 ...

随机推荐

  1. java调用js代码

    jdk8里使用脚本引擎调用js 1.定义一个js方法: function getRouteInfo(province){ //注意,参数不要带var..在java里执行会报错.. if (provin ...

  2. .NET 5网络操作的改进

    随着.net 5在11月的发布,现在是谈论网络栈中许多改进的好时机.这包括对HTTP.套接字.与网络相关的安全性和其他网络通信的改进.在这篇文章中,我将重点介绍一些版本中更有影响力和更有趣的变化. H ...

  3. Java进阶专题(二十一) 消息中间件架构体系(3)-- Kafka研究

    前言 Kafka 是一款分布式消息发布和订阅系统,具有高性能.高吞吐量的特点而被广泛应用与大数据传输场景.它是由 LinkedIn 公司开发,使用 Scala 语言编写,之后成为 Apache 基金会 ...

  4. three.js 之cannon.js物理引擎

    今天郭先生说的是一个物理引擎,它十分小巧并且操作简单,没错他就是cannon.js.这些优点都源自于他是基于js编写的,对于js使用者来说cannon.js拥有其他物理引擎没有的纯粹性.从学习成本来看 ...

  5. 使用 C# 9 的records作为强类型ID - JSON序列化

    在本系列的上一篇文章中,我们注意到强类型ID的实体,序列化为 JSON 的时候报错了,就像这样: { "id": { "value": 1 }, "n ...

  6. 【Linux】E297: Write error in swap file 解决办法

    今天登陆到服务器上,发现通过vi 打开文件就会报错: E297: Write error in swap file E303: Unable to open swap file for "c ...

  7. ctfhub技能树—RCE—综合过滤练习

    打开靶机 查看页面信息 查看源码可以发现这一次过滤了很多东西,查看当前目录信息 查询到%0a为换行符,可以利用这个url编码进行命令注入,开始尝试 http://challenge-2a4584dab ...

  8. ftp交互和控制命令总结

    一.FTP管理: 基于tcp,首先有客户端相服务端的知名端口21发起tcp连接建立ftp控制连接,控制连接在整个会话期间都保持打开,只用来发送连接/传送请求. 这里分为两种模式: 主动模式(PORT) ...

  9. Genymotion虚拟机用键盘输入中文

    genymotion我用的版本是3.0.4,安卓内核版本从4到9都进行了尝试,尤其是教新的版本原生是不带中文输入法的. 前提:安装Genymotion以后,想要随意安装app,需要先安装Genymot ...

  10. 1.5V转5V的最少电路的芯片电路图

    PW5100满足1.5V转5V的很简洁芯片电路,同时达到了最少的元件即可组成DC-DC电路1.5V转5V的升压转换器系统. PW5100在1.5V转5V输出无负载时,输入效率电流极低,典型值10uA. ...