Problem A. Two distinct points

[题解]

显然 , 当l1不等于r2时 , (l1 , r2)是一组解

否则 , (l1 , l2)是一组合法的解

时间复杂度 : O(1)

[代码]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
int main()
{ int T;
read(T);
while (T--)
{
int l1 , r1 , l2 , r2;
read(l1); read(r1); read(l2); read(r2);
if (l1 != r2) cout<< l1 << ' ' << r2 << '\n';
else cout<< l1 << ' ' << l2 << '\n';
}
return ; }

Problem B. Divisors of Two Integers

[题解]

首先 , 给定序列中的最大数一定是x和y中的一个数

将该数的所有因子从序列中删除一次 , 剩余数中的最大数即为另一个数

时间复杂度 : O(M) (取M = 10 ^ 4)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 10010
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; int n;
int d[MAXN] , cnt[MAXN]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
int main()
{ read(n);
int fst = , sec = ;
for (int i = ; i <= n; i++)
{
read(d[i]);
if (d[i] > fst) fst = d[i];
++cnt[d[i]];
}
for (int i = ; i <= fst; i++)
if (fst % i == ) --cnt[i];
for (int i = (int)1e4; i >= ; i--)
{
if (cnt[i])
{
sec = i;
break;
}
}
cout<< fst << ' ' << sec << '\n'; return ; }

Problem C. Nice Garland

[题解]

通过观察发现 , 答案一定是一个以"R" , "G" , "B"三个字符所形成的一个排列为循环节循环得到的字符串

枚举排列 , 计算最优解 , 即可

时间复杂度 : O(N)

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + ;
const int inf = 1e9;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; int n;
char s[MAXN] , t1[MAXN] , t2[MAXN] , t3[MAXN] , t4[MAXN] , t5[MAXN] , t6[MAXN]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
int main()
{ scanf("%d" , &n);
scanf("%s" , s + );
for (int i = ; i <= n; i++)
{
if (i % == ) t1[i] = 'R';
if (i % == ) t1[i] = 'G';
if (i % == ) t1[i] = 'B';
}
int stp = , ans = , mstp = inf;
for (int i = ; i <= n; i++)
if (s[i] != t1[i]) ++stp;
if (stp < mstp)
{
mstp = stp;
ans = ;
} for (int i = ; i <= n; i++)
{
if (i % == ) t2[i] = 'R';
if (i % == ) t2[i] = 'B';
if (i % == ) t2[i] = 'G';
}
stp = ;
for (int i = ; i <= n; i++)
if (s[i] != t2[i]) ++stp;
if (stp < mstp)
{
mstp = stp;
ans = ;
} for (int i = ; i <= n; i++)
{
if (i % == ) t3[i] = 'B';
if (i % == ) t3[i] = 'R';
if (i % == ) t3[i] = 'G';
}
stp = ;
for (int i = ; i <= n; i++)
if (s[i] != t3[i]) ++stp;
if (stp < mstp)
{
mstp = stp;
ans = ;
} for (int i = ; i <= n; i++)
{
if (i % == ) t4[i] = 'B';
if (i % == ) t4[i] = 'G';
if (i % == ) t4[i] = 'R';
}
stp = ;
for (int i = ; i <= n; i++)
if (s[i] != t4[i]) ++stp;
if (stp < mstp)
{
mstp = stp;
ans = ;
} for (int i = ; i <= n; i++)
{
if (i % == ) t5[i] = 'G';
if (i % == ) t5[i] = 'R';
if (i % == ) t5[i] = 'B';
}
stp = ;
for (int i = ; i <= n; i++)
if (s[i] != t5[i]) ++stp;
if (stp < mstp)
{
mstp = stp;
ans = ;
} for (int i = ; i <= n; i++)
{
if (i % == ) t6[i] = 'G';
if (i % == ) t6[i] = 'B';
if (i % == ) t6[i] = 'R';
}
stp = ;
for (int i = ; i <= n; i++)
if (s[i] != t6[i]) ++stp;
if (stp < mstp)
{
mstp = stp;
ans = ;
} cout<< mstp << '\n';
if (ans == )
{
for (int i = ; i <= n; i++) putchar(t1[i]);
cout<< '\n';
}
if (ans == )
{
for (int i = ; i <= n; i++) putchar(t2[i]);
cout<< '\n';
}
if (ans == )
{
for (int i = ; i <= n; i++) putchar(t3[i]);
cout<< '\n';
}
if (ans == )
{
for (int i = ; i <= n; i++) putchar(t4[i]);
cout<< '\n';
}
if (ans == )
{
for (int i = ; i <= n; i++) putchar(t5[i]);
cout<< '\n';
}
if (ans == )
{
for (int i = ; i <= n; i++) putchar(t6[i]);
cout<< '\n';
} return ; }

Problem D.  Diverse Garland

[题解]

简单贪心即可

时间复杂度 : O(N)

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + ;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; int n , cnt;
char s[MAXN]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
int main()
{ scanf("%d" , &n);
scanf("%s" , s + );
map<char , int> mp;
mp.clear();
for (int i = ; i < n; i++)
{
if (s[i] != s[i - ]) continue;
mp.clear();
mp[s[i - ]]++; mp[s[i + ]]++;
if (mp['R'] && mp['G'])
{
s[i] = 'B';
++cnt;
} else if (mp['R'] && mp['B'])
{
s[i] = 'G';
++cnt;
} else if (mp['B'] && mp['G'])
{
s[i] = 'R';
++cnt;
} else if (mp['R'])
{
s[i] = 'G';
++cnt;
} else if (mp['G'])
{
s[i] = 'B';
++cnt;
} else
{
s[i] = 'R';
++cnt;
}
}
if (s[n] == s[n - ])
{
  

int i = n;
          mp.clear();
          ++mp[s[n - 1]];
          if (mp['R'])
          {
             s[i] = 'G';
             ++cnt;
          } else if (mp['G'])
          {
              s[i] = 'B';
              ++cnt;
          } else
          {
         s[i] = 'R';
         ++cnt;
         }

}

        cout<< cnt << '\n';
for (int i = ; i <= n; i++) putchar(s[i]);
printf("\n"); return ; }

Problem E. Array and Segments

[题解]

       Easy Version :

       枚举序列中的最大值和最小值的出现位置 , 然后枚举每一条线段 , 贪心地选择所有覆盖了最小值出现位置的线段

时间复杂度 : O(N ^ 2M)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 310
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; int n , m , ans;
int a[MAXN] , l[MAXN] , r[MAXN];
vector< int > fans; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void solve(int x , int y)
{
int tx = a[x] , ty = a[y];
vector< int > res;
res.clear();
for (int i = ; i <= m; i++)
{
if (l[i] <= x && r[i] >= x) continue;
if (l[i] <= y && r[i] >= y)
{
res.push_back(i);
--ty;
}
}
if (tx - ty > ans)
{
ans = tx - ty;
fans.clear();
for (unsigned i = ; i < res.size(); i++) fans.push_back(res[i]);
}
} int main()
{ read(n); read(m);
for (int i = ; i <= n; i++) read(a[i]);
for (int i = ; i <= m; i++)
{
read(l[i]);
read(r[i]);
}
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
{
if (i != j)
solve(i , j);
}
}
cout<< ans << '\n';
cout<< (int)fans.size() << '\n';
for (unsigned i = ; i < (int)fans.size(); i++) cout<< fans[i] << ' ';
cout<< '\n'; return ; }

Hard Version :

                      我们可以先选择所有线段           

                      那么 , 问题就转化为 , 选择一些区间进行操作 , 使得[li , ri]每个数增加1 , 最大化序列中的最大值 - 最小值

考虑枚举最大值出现的位置 , 显然 , 我们可以贪心地选择所有覆盖了该位置的线段

那么我们就可以使用扫描线算法 :

从1-n按顺序枚举最大值出现的位置i , 考虑所有以i为左端点的线段 , 我们选择这些线段进行操作 , 然后考虑所有以i为右端点的线段 , 取消对这些线段的操作

维护一棵支持区间修改 , 询问区间最大 / 最小值的线段树即可

时间复杂度 : O(NMlogN)

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + ; #pragma GCC optimize(2)
#define rint register int typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; int n , m;
int l[MAXN] , r[MAXN] , val[MAXN];
vector< int > s[MAXN] , e[MAXN];
bool tag[MAXN]; struct Segment_Tree
{
struct Node
{
int l , r , tag;
pair<int , int> value;
} a[MAXN << ];
inline void build(int index , int l , int r)
{
a[index].l = l , a[index].r = r;
a[index].tag = ;
if (l == r)
{
a[index].value = make_pair(val[l] , val[l]);
return;
}
int mid = (l + r) >> ;
build(index << , l , mid);
build(index << | , mid + , r);
update(index);
}
inline void update(int index)
{
a[index].value.first = min(a[index << ].value.first , a[index << | ].value.first);
a[index].value.second = max(a[index << ].value.second , a[index << | ].value.second);
}
inline void pushdown(int index)
{
a[index << ].value.first += a[index].tag;
a[index << | ].value.first += a[index].tag;
a[index << ].value.second += a[index].tag;
a[index << | ].value.second += a[index].tag;
a[index << ].tag += a[index].tag;
a[index << | ].tag += a[index].tag;
a[index].tag = ;
}
inline void modify(int index , int l , int r , int val)
{
if (a[index].l == l && a[index].r == r)
{
a[index].value.first += val;
a[index].value.second += val;
a[index].tag += val;
return;
}
pushdown(index);
int mid = (a[index].l + a[index].r) >> ;
if (mid >= r) modify(index << , l , r , val);
else if (mid + <= l) modify(index << | , l , r , val);
else
{
modify(index << , l , mid , val);
modify(index << | , mid + , r , val);
}
update(index);
}
inline pair<int , int> query()
{
return a[].value;
}
} SGT; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
} int main()
{ read(n); read(m);
for (rint i = ; i <= n; i++) read(val[i]);
SGT.build( , , n);
for (rint i = ; i <= m; i++)
{
read(l[i]);
read(r[i]);
s[l[i]].push_back(r[i]);
e[r[i]].push_back(l[i]);
SGT.modify( , l[i] , r[i] , -);
}
int mx = , loc = ;
for (rint i = ; i <= n; i++)
{
for (unsigned j = ; j < s[i].size(); j++)
SGT.modify( , i , s[i][j] , );
pair<int , int> tmp = SGT.query();
if (tmp.second - tmp.first > mx)
{
mx = tmp.second - tmp.first;
loc = i;
}
for (unsigned j = ; j < e[i].size(); j++)
SGT.modify( , e[i][j] , i , -);
}
cout<< mx << '\n';
vector< int > res;
for (int i = ; i <= m; i++)
{
if (l[i] > loc || r[i] < loc)
res.push_back(i);
}
cout<< (int)res.size() << '\n';
for (unsigned i = ; i < res.size(); i++) cout<< res[i] << ' ';
cout<< '\n'; return ; }

Problem F. MST Unification

[题解]

首先用kruskal算法求出这个图的任意一棵最小生成树

枚举不在这颗最小生成树上的每一条边(u , v , w)

若加入这条边 , 则形成了一个环 , 若环上的边权除这条边外的最大值 = w , 那么说明可以用这条边替换环上权值 = w的边 , 我们需要将这条边的权值加一

倍增即可

时间复杂度 : O((N + M)logN)

[代码]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int MAXN = 2e5 + ;
const int MAXLOG = ; struct Edge
{
int x,y;
long long w;
} edge[MAXN << ]; int T,n,m,i;
long long val;
vector< pair<int,long long> > e[MAXN];
bool on_mst[MAXN];
int fa[MAXN],anc[MAXN][MAXLOG],dep[MAXN];
long long mx[MAXN][MAXLOG];
bool not_unique; inline bool cmp(Edge a,Edge b) { return a.w < b.w; }
inline int get_root(int x)
{
if (fa[x] == x) return x;
return fa[x] = get_root(fa[x]);
}
inline void kruskal()
{
int i,x,y,sx,sy;
long long w;
for (i = ; i <= n; i++) fa[i] = i;
for (i = ; i <= m; i++) on_mst[i] = false;
sort(edge+,edge+m+,cmp);
for (i = ; i <= m; i++)
{
x = edge[i].x;
y = edge[i].y;
w = edge[i].w;
sx = get_root(x);
sy = get_root(y);
if (sx != sy)
{
on_mst[i] = true;
val += w;
fa[sx] = sy;
e[x].push_back(make_pair(y,w));
e[y].push_back(make_pair(x,w));
}
}
}
inline void build(int u)
{
int i,v;
for (i = ; i < MAXLOG; i++)
{
anc[u][i] = anc[anc[u][i-]][i-];
mx[u][i] = max(mx[u][i-],mx[anc[u][i-]][i-]);
}
for (i = ; i < e[u].size(); i++)
{
v = e[u][i].first;
if (anc[u][] != v)
{
dep[v] = dep[u] + ;
anc[v][] = u;
mx[v][] = e[u][i].second;
build(v);
}
}
}
inline long long get(int x,int y)
{
int i,t;
long long ans = ;
if (dep[x] > dep[y]) swap(x,y);
t = dep[y] - dep[x];
for (i = ; i < MAXLOG; i++)
{
if (t & ( << i))
{
ans = max(ans,mx[y][i]);
y = anc[y][i];
}
}
if (x == y) return ans;
for (i = MAXLOG - ; i >= ; i--)
{
if (anc[x][i] != anc[y][i])
{
ans = max(ans,max(mx[x][i],mx[y][i]));
x = anc[x][i];
y = anc[y][i];
}
}
return max(ans,max(mx[x][],mx[y][]));
}
int main()
{ scanf("%d%d",&n,&m);
val = ;
not_unique = false;
for (i = ; i <= n; i++)
{
dep[i] = ;
e[i].clear();
memset(anc[i],,sizeof(anc[i]));
memset(mx[i],,sizeof(mx[i]));
}
for (i = ; i <= m; i++) scanf("%d%d%lld",&edge[i].x,&edge[i].y,&edge[i].w);
kruskal();
build();
int ans = ;
for (i = ; i <= m; i++)
{
if (!on_mst[i])
ans += (get(edge[i].x,edge[i].y) == edge[i].w);
}
cout<< ans << '\n'; return ; }

Codeforces Round #535(div 3) 简要题解的更多相关文章

  1. Codeforces Round #557 (Div. 1) 简要题解

    Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...

  2. Codeforces Round #545 (Div. 1) 简要题解

    这里没有翻译 Codeforces Round #545 (Div. 1) T1 对于每行每列分别离散化,求出大于这个位置的数字的个数即可. # include <bits/stdc++.h&g ...

  3. Codeforces Round #483 (Div. 1) 简要题解

    来自FallDream的博客,未经允许,请勿转载,谢谢. 为了证明一下我又来更新了,写一篇简要的题解吧. 这场比赛好像有点神奇,E题莫名是道原题,导致有很多选手直接过掉了(Claris 表演24s过题 ...

  4. Codeforces Round #498 (Div. 3) 简要题解

    [比赛链接] https://codeforces.com/contest/1006 [题解] Problem A. Adjacent Replacements        [算法] 将序列中的所有 ...

  5. [题解][Codeforces]Codeforces Round #602 (Div. 1) 简要题解

    orz djq_cpp lgm A 题意 给定一个分别含有 \(\frac n2\) 个左括号和右括号的括号序列 每次可以将序列的一个区间翻转 求一个不超过 \(n\) 次的操作方案,使得操作完之后的 ...

  6. Codeforces Round #398 (div.2)简要题解

    这场cf时间特别好,周六下午,于是就打了打(谁叫我永远1800上不去div1) 比以前div2的题目更均衡了,没有太简单和太难的...好像B题难度高了很多,然后卡了很多人. 然后我最后做了四题,E题感 ...

  7. Codeforces Round #588 (Div. 1) 简要题解

    1. 1229A Marcin and Training Camp 大意: 给定$n$个对$(a_i,b_i)$, 要求选出一个集合, 使得不存在一个元素好于集合中其他所有元素. 若$a_i$的二进制 ...

  8. Codeforces Round #576 (Div. 1) 简要题解 (CDEF)

    1198 C Matching vs Independent Set 大意: 给定$3n$个点的无向图, 求构造$n$条边的匹配, 或$n$个点的独立集. 假设已经构造出$x$条边的匹配, 那么剩余$ ...

  9. Codeforces Round #535 (Div. 3) 题解

    Codeforces Round #535 (Div. 3) 题目总链接:https://codeforces.com/contest/1108 太懒了啊~好久之前的我现在才更新,赶紧补上吧,不能漏掉 ...

随机推荐

  1. Git以及github的使用方法(六),管理修改

    现在,假定你已经完全掌握了暂存区的概念.下面,我们要讨论的就是,为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件. 你会问,什么是修改?比如你新增了一行,这就是一个修改 ...

  2. 修改 本地 IP 及 正则表达式 test exec match 的区别

    修改 IP 1.打开 "打开网络和共享中心" 2.打开 "更改适配器设置" 3.打开 "本地连接" 属性 4.修改 "协议版本 4 ...

  3. yarn 基本用法

    1.初始化一个新的项目 yarn init 2.添加一个依赖包 yarn add [package] yarn add [package]@[version] yarn add [package]@[ ...

  4. Ffmpeg 实现文件切割

    文件切割是一项很常见的基本功能,通过Ffmpeg可以很容易实现这项功能. 首先介绍下基本原理,文件切割说白了就过滤掉文件的部分音视频包,按照什么规则过滤呢? 答案是时间戳.文件中每个视频及音频包都有时 ...

  5. spl_autoload_register的使用

    class Loader{ static function loadClass($class) { $class = $class.'.php'; if(file_exists($class)) { ...

  6. PCIE、UART、HDA、I2C、SMBUS、SPI、eSPI、USB、PS2、CAN、SDIO等数据传输协议简介

    M.2 wife一般支持USB.SDIO.PCIE三种传输 1.摄像头 (1)MIPI CSI (2)USB mipi摄像头模组IC简单便宜(小),应为一般把ADC解码在CPU端. MIPI摄像头简介 ...

  7. Install Server Backup Manager on CentOS, RHE, and Fedora

    Skip to end of metadata Added by Internal, last edited by Internal on Aug 25, 2014 Go to start of me ...

  8. Redis 3.2.4编译安装

    1. 下载安装包 wget url tar zxvf redis-3.2.4.tar.gz 2. 编译安装 cd redis-3.2.4/src/ sudo make && make ...

  9. ORACLE时间函数(SYSDATE)简析

    ORACLE时间函数(SYSDATE)简析 分类: 原文地址:ORACLE时间函数(SYSDATE)简析 作者:skylway 加法 select sysdate,add_months(sysdate ...

  10. EasyRTMP实现将RTSP流转换成RTMP流实现RTSP直播转RTMP直播的功能

    本文转自EasyDarwin开源团队Kim的博客:http://blog.csdn.net/jinlong0603/article/details/52951311 EasyRTMP EasyRTMP ...