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. DICOM医学图像处理:深入剖析Orthanc的SQLite,了解WADO & RESTful API

    背景: 上一篇博文简单翻译了Orthanc官网给出的CodeProject上“利用Orthanc Plugin SDK开发WADO插件”的博文,其中提到了Orthanc从0.8.0版本之后支持快速查询 ...

  2. [反汇编练习] 160个CrackMe之028

    [反汇编练习] 160个CrackMe之028. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  3. 您也使用托管C++吗? 【转】

    http://blog.csdn.net/Muf/article/details/656920 转向.NET后,手头上往往仍有旧的模块要重用.也许这些模块是Delphi写的,也许是C/C++写的,或者 ...

  4. 深度排序与alpha混合 【转】

      翻译:李现民 最后修改:2012-07-03 原文:Depth sorting alpha blended objects 先说个题外话,本来我想回答在 Creators Club论坛上的一个常见 ...

  5. gvim的常用编辑快捷键

    gvim的快捷键很多,很难记全,但是入门初期应该找过几种基本的命令 下面结合自己常用到的介绍下 光标跳转: 0:行首 $:行尾 e:下一个单词的结尾 w:下一个单词的开头 b:上一个单词 H:当前页面 ...

  6. live555client连多路1080P视频流花屏问题

    硬件和软件环境是这种: DM8168 + linux. 解码器是DM8168自带的 视频来源: ipc通过live555做的的rtsp sever发送过来的 其它測试: 通过VLC在pc连4路1080 ...

  7. ios You app information could not be saved. Try again. If the problem persists, contact us

    ios You app information could not be saved. Try again. If the problem persists, contact us  大概意思:你的a ...

  8. ZipOutputStream 用法 小计

    ZipOutputStream s = new ZipOutputStream(File.Create(ZipedFile)); 构造函数之后 文件就已经创建出来了 只是 0kb s.Write(bu ...

  9. HDU 2102 A计划 (BFS)

    A计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  10. Springmvc返回信息乱码解决

    恩...基本上所有的配置信息都弄上了,但是还是乱码,最后在方法上面添加了下面的参数,就完美解决了: @RequestMapping(value="/action.action",m ...