Codeforces Round #809 (Div. 2)

2022/7/19 下午VP

传送门https://codeforces.com/contest/1706

A. Another String Minimization Problem

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int a[N];
signed main() {
std::ios::sync_with_stdio(false);
int t;std::cin>>t;
while(t--){
int n,m;std::cin>>n>>m;
for(int i=1;i<=n;i++)std::cin>>a[i];
std::string s;for(int i=1;i<=m;i++)s+='B';
for(int i=1;i<=n;i++){
int l = a[i]-1,r=m-a[i];
if(l>r)std::swap(l,r);
if(s[l]=='A')s[r]='A';
else s[l]='A';
}
std::cout<<s<<"\n";
}
}

B. Making Towers

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int c[N];
int ans[N];
int last[N];
signed main() {
std::ios::sync_with_stdio(false);
int t;std::cin>>t;
while(t--){
int n;std::cin>>n;
for(int i=1;i<=n;i++)ans[i]=0;
for(int i=1;i<=n;i++)last[i]=0;
for(int i=1;i<=n;i++)std::cin>>c[i];
for(int i=1;i<=n;i++){
if(last[c[i]]==0||(i-last[c[i]])%2==1){
ans[c[i]]++;
last[c[i]]=i;
}
}
for(int i=1;i<=n;i++)std::cout<<ans[i]<<" \n"[i==n];
}
}

C. Qpwoeirut And The City

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int h[N];
int dp[N][2];
signed main() {
std::ios::sync_with_stdio(false);
int t;std::cin>>t;
while(t--){
int n;std::cin>>n;
dp[0][1]=dp[0][0]=dp[1][0]=dp[1][1]=0;
for(int i=2;i<=n;i++)dp[i][0]=dp[i][1]=1e17;
for(int i=1;i<=n;i++)std::cin>>h[i];
for(int i=2;i<=n;i++){
dp[i][0]=dp[i-2][0]+std::max(0ll,std::max(h[i-1],h[i+1])-h[i]+1);
if(i!=2)dp[i][1]=std::min(dp[i-2][1],dp[i-3][0])+std::max(0ll,std::max(h[i-1],h[i+1])-h[i]+1);
}
if(n&1)std::cout<<dp[n-1][0]<<"\n";
else std::cout<<std::min({std::min(dp[n-1][0],dp[n-1][1]),dp[n-2][0]})<<"\n";
}
}

D1. Chopping Carrots (Easy Version)

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int a[N];int n,k;
int check(int p){
int maxs=1;
for(int i=1;i<=n;i++){
int ma=1e17;
for(int j=1;j<=k;j++){
if(a[i]/j>=p){
ma=std::min(ma,a[i]/j);
}
else break;
}
maxs=std::max(maxs,ma);
}
return maxs-p;
}
signed main() {
std::ios::sync_with_stdio(false);
int t;std::cin>>t;
while(t--){
std::cin>>n>>k;
for(int i=1;i<=n;i++){
std::cin>>a[i];
}
int ans=1e17;
for(int mins=0;mins<=a[1];mins++){
ans=std::min(ans,check(mins));
}
std::cout<<ans<<"\n";
}
}

D2. Chopping Carrots (Hard Version)

整除分块

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int a[N];int n,k;
int ans[N];//以i为最小值的max
void init(){//整除分块
for(int i=0;i<N;i++)ans[i]=i;
int last=1e17;
for(int i=1;i<=n;i++){
for(int l=1,r;l<=std::min(a[i],k);l=r+1){
r=a[i]/(a[i]/l);
int v=a[i]/l;
ans[v+1]=std::max(ans[v+1],last);
last=v;
}
ans[0]=std::max(ans[0],last);
}
for(int i=1;i<=a[1];i++)ans[i]=std::max(ans[i],ans[i-1]);
}
signed main() {
std::ios::sync_with_stdio(false);
int t;std::cin>>t;
while(t--){
std::cin>>n>>k;
for(int i=1;i<=n;i++)std::cin>>a[i];
init();
int anss=1e17; for(int i=0;i<=a[1];i++){
anss=std::min(ans[i]-i,anss);
}
std::cout<<anss<<"\n";
}
}

E. Qpwoeirut and Vertices

题意:t组输入。每组由n个顶点,m条边的连通无向图,q次询问。

每次询问一个区间l,r。求使得[l,r]的所有顶点互相可达的最小的k。k是选取的[1,k]条边。

解法1(最小生成树,LCA,st表):

参考yaqu姐姐的代码参悟的:https://codeforces.com/contest/1706/submission/164890534

问题转化为:一颗权值为边的编号的最小生成树,找到[1,k]两两可达的所有边的最大边权。

在树上找两点间路径的最大边权,就是在找最近公共祖先的路上顺便记录最大值。用倍增实现即可。

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int fa[N];int n,m,q;
int st[N][30];//点间最大值st表
int father[N][30],maxst[N][30];//父节点倍增,边权倍增
int dep[N];//深度
struct Edge{
int from,to,k;//两个端点,权值。
};
std::vector<Edge>edge;//边集
std::vector<std::pair<int,int>>to[N];
void clear(){
edge.clear();
for(int i=0;i<=n;i++)fa[i]=i;
for(int i=0;i<=n;i++)to[i].clear();
for(int i=0;i<=n;i++){for(int j=0;j<30;j++)maxst[i][j]=st[i][j]=father[i][j]=0;}
for(int i=0;i<=n;i++)dep[i]=0;
}
int find(int x) {return fa[x] == x ? x :fa[x]=find(fa[x]);} //并查集路径压缩
void Kruskal(){//最小生成树
for(Edge i:edge){
int x=find(i.from);
int y=find(i.to);
if(x==y)continue;
fa[x]=y;
to[x].push_back({y,i.k});to[y].push_back({x,i.k});
}
}
int lca(int x,int y){
int ans=0;
if(dep[x]>dep[y])std::swap(x,y);
if (dep[y] > dep[x])std::swap(x, y);
for (int i = 20; i >= 0; i--) {
if (father[x][i] && dep[father[x][i]] >= dep[y]){
ans=std::max(ans,maxst[x][i]);
x = father[x][i];
}
}
if(x==y)return ans;
for(int i=20;i>=0;i--){
if(father[x][i]!=father[y][i]){
ans=std::max(ans,std::max(maxst[x][i],maxst[y][i]));
x=father[x][i];
y=father[y][i];
}
}
return ans=std::max(ans,std::max(maxst[x][0],maxst[y][0]));
}
void dfs(int son,int last){
father[son][0]=last;
dep[son]=dep[last]+1;
for(auto k:to[son]){
if(k.first!=last){
maxst[k.first][0]=maxst[k.first][1]=k.second;
dfs(k.first,son);
}
}
}
void init(){
Kruskal();//建树
int root=find(1);//最小生成树的树根
dfs(root,0);//找到根,开始dfs
for(int i=1;i<=20;i++)for(int j=1;j<=n;j++)father[j][i]=father[father[j][i-1]][i-1];
for(int i=1;i<=20;i++)for(int j=1;j<=n;j++)maxst[j][i]=std::max(maxst[father[j][i-1]][i-1],maxst[j][i-1]);
for(int i=1;i<n; i++) {st[i][0]=lca(i,i+1);}
for (int i=1;i<=20;i++) {
for (int j=1;j+(1ll<<i)-1<=n;j++) {
st[j][i]=std::max(st[j][i-1],st[j+(1<<(i-1))][i-1]);
}
}
}
int query(int l,int r){
int x=log2(r-l+1);
return std::max(st[l][x],st[r-(1<<x)+1][x]);
}
int slove(int l,int r){
int ans=0;
if(l==r)return 0;
if(l==r-1)return st[l][0];
return query(l,r-1); }
signed main() {
std::ios::sync_with_stdio(false);
int t;std::cin>>t;
while(t--){
std::cin>>n>>m>>q;
std::vector<int>ans;
clear();
for(int i=0;i<m;i++){
int a,b;std::cin>>a>>b;
edge.push_back({a,b,i+1});
}
init();
while(q--){
int l,r;std::cin>>l>>r;
ans.push_back(slove(l,r));
}
for(int i=0;i<ans.size();i++)std::cout<<ans[i]<<" \n"[i==ans.size()-1];
}
}

解法2(启发式合并+st表):

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int n,m,q;
int fa[N],st[N][20];
std::vector<int>to[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} //并查集路径压缩
void clear(){
for(int i=0;i<=n;i++)fa[i]=i;
for(int i=0;i<=n;i++){
to[i].clear();
to[i].push_back(i);
}
}
int query(int l,int r){//st表查询
int k=log2(r-l+1);
return std::max(st[l][k],st[r-(1<< k)+1][k]);
}
int slove(int l,int r){
if(l==r)return 0;
return query(l,r-1);
}
void merge(int x,int y,int k){//把小的点集合并到大的上面。
if(to[x].size()>to[y].size())std::swap(x,y);
for(int i:to[x]){
if(find(i+1)==y)st[i][0]=k;//找小点集在大点集里是否有相邻点。
if(find(i-1)==y)st[i-1][0]=k;
to[y].push_back(i);
}
fa[x]=y;//合并
}
signed main() {
std::ios::sync_with_stdio(false);
int t;std::cin>>t;
while(t--){
std::cin>>n>>m>>q;
std::vector<int>ans;
clear();
for(int i=1;i<=m;i++){
int a,b;std::cin>>a>>b;
int x=find(a);int y=find(b);
if(x==y)continue;
merge(x,y,i);
}
for (int j = 1; j <= 20; j++) {
for (int i = 1; i + (1 << j) - 1 <= n; i ++) {
st[i][j] = std::max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
}
}
while(q--){
int l,r;std::cin>>l>>r;
ans.push_back(slove(l,r));
}
for(int i=0;i<ans.size();i++)std::cout<<ans[i]<<" \n"[i==ans.size()-1];
}
}

Codeforces Round #809 (Div. 2) A-E的更多相关文章

  1. Codeforces Round #809 (Div. 2)C.Qpwoeirut And The City

    题目大意: 当一栋楼比旁边两栋楼都高的时候,这栋楼为cool,对除了1和n以外的所有楼可以增加任意层,问在满足使最多的楼cool的前提下的花费最小. 当n为奇数的情况下: cool的楼实际上是固定的, ...

  2. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  3. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  4. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  5. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  6. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  7. Codeforces Round #262 (Div. 2) 1003

    Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...

  8. Codeforces Round #262 (Div. 2) 1004

    Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...

  9. Codeforces Round #371 (Div. 1)

    A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...

  10. Codeforces Round #268 (Div. 2) ABCD

    CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...

随机推荐

  1. Python常用技巧工具【不断更新】

    一.**kwargs用法 # **kwargs用法#双星"**"放在字典的前面可以让你将字典的内容作为命名参数传递给函数.#字典的键是参数的名字,键的值作为参数的值传递给函数dic ...

  2. JS学习-给Canvas上下文设置样式

    给Canvas上下文设置样式 <canvas class="myCanvas" width="700" height="500"> ...

  3. ASP.NET Core连接字符串中的特殊字符如何处理?多实例如何连接?

    ASP.NET Core连接字符串中的特殊字符,如数据库密码,有时会有特殊字符,如password&1234, 如何直接使用会报连接错误,只需用单引号阔起来即可,如下'password& ...

  4. 【Numpy】安装Anaconda3和调试

    1,在Anaconda官网下载一个对应操作系统的安装包:https://www.anaconda.com/distribution/ 2,然后选版本操作系统和版本号,下载完成后安装 3,windows ...

  5. Date 日期字符串自定义格式化

    Date.prototype.Format = function (fmt) { var o = { "M+": this.getMonth() + 1, //月份 "d ...

  6. HDFS学习记录

    HDFS 1.hdfs整体工作机制: 1>hdfs:分布式文件系统. hdfs:分布式文件系统 hdfs有着文件系统共同的特征: 2>有目录结构,顶层目录是:  / 3>系统中存放的 ...

  7. libevent学习之入门--[02]从hello-world开始

    系列文章回顾 libevent学习之入门--[01]概述与安装 上一节介绍了libevent的下载和编译,从这节开始,我会从我学习的角度逐步探索libevent的源码,慢慢揭开它的神秘面纱. 面对几十 ...

  8. JLink OB SWI 取代串口打印的方式

    1:debug的串口被占用 2:从Keil 迁移到的LINUX下开发. 3:手上只有JLinkOB,(4线:CLK,SWIO,GND,RST) 4:设备只引出了4线(SWO 没接出) 环境: JLin ...

  9. Docker基本命令之 仓库管理(docker hub)

    仓库管理 仓库介绍:仓库(Repository)就是集中存放镜像的地方 登录docker hub注册一个自己的账号 然后创建一个仓库:xxx 登录:docker login -- 输入用户名/密码(退 ...

  10. WebStore 破解

    前提 你需要首先安装该软件,并下载补丁,不过这些已经为你打包好了. WebStore 2020.1 , jetbrains-agent.jar , resources_zh_CN_WebStorm_2 ...