比赛地址

A(水题)

题目链接

题目:

给出指定\(n\),求解出一段区间\([l,r]\)使得\(\sum\limits_{i=l}^ri=n\)

解析:

从点0,1两点作为起点分别向左右延伸长度,每次延伸单位长度时,这段区间和也加1,因此答案为\([1-n,n]\)

#include<bits/stdc++.h>
using namespace std; int main() {
int T;
long long t;
scanf("%d", &T);
while (T--) {
scanf("%lld", &t);
printf("%lld %lld\n", 1 - t, t);
}
}

B(水题)

题目链接

题目:

给出底数\(n\),由若干不同的\(n^i(i\ge0)\)组成的数中,第\(k\)大的数是多少

解析:

即\(n^i\)只有出现或者不出现两种可能,也就是说它的系数只能是0或1,这样第\(k\)大对应的系数即为\(k\)对应的二进制形式

#include<bits/stdc++.h>
using namespace std; long long n, k, mod = 1e9 + 7; int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%lld%lld", &n, &k);
long long t = 1, ans = 0;
while (k) {
if (k & 1) ans = (ans + t) % mod;
k >>= 1;
t = t * n % mod;
}
printf("%lld\n", ans);
}
}

C(埃筛)

题目链接

题目:

给出一组下标\(a(a_i\le n)\),每次可以指定一个\(x\),将\(x\nmid a_i\)则消除\(a_i\),问最少指定几个\(x\)

解析:

  • 对于特殊情况如果\(a\)的长度为\(0\),则直接输出\(0\)
  • 考虑如何一次清除,可以用类似埃筛的思想,对于任意一个不在\(a\)中的下标,考虑它小于\(n\)的倍数是否在数组中,如果均不在数组中,则输出这个值

    优化: 考虑证明结论如果n的后一半数中,存在某个值不在下标序列中,则这个值可以作为答案。充分性显然成立,必要性考虑\(n\)的前一半数如果作为答案,则一定有一个它的倍数属于\(n\)的后一半数,且不在下标序列中
  • 上述情况都不满足时,输出\(n,n-1\)即可消除所有的数(因为\(x=n\)时,无法消除\(n\))
#include<bits/stdc++.h>
using namespace std; const int maxn = 3e5 + 5;
char str[maxn]; int main() {
int T;
int n;
char ch;
scanf("%d", &T);
while (T--) {
scanf("%d %c%s", &n, &ch, str);
bool ok = 0;
for (int i = 0; i < n; ++i)
if (str[i] != ch) {
ok = true;
break;
}
if (ok) {
for (int i = n / 2; i < n; ++i) {
if (str[i] == ch) {
ok = false;
printf("1\n%d\n", i + 1);
break;
}
}
if (ok)
printf("2\n%d %d\n", n - 1, n);
}
else printf("0\n");
}
}

D(带权并查集)

题目链接

题目:

现在有\(n\)个人,有诚实的人也有撒谎的人。诚实的人只说真话,撒谎的人只说假话,他们共说了\(m\)句话,以\(i\quad j\quad identity\)的形式给出,代表\(i\)认为\(j\)是什么身份,如果言语不合法则输出-1,否则输出最多的撒谎者个数

解析:

这道题与UVA 10158非常类似,如果\(i\)认为\(j\)是诚实的人,则\(i,j\)同真同假,反之一真一假,设\([1,n]\)代表1\(\sim n\)是诚实的人的情况,\([n+1,2n]\)代表是撒谎者的情况,初始时对于所有撒谎情况赋予权重1

  • 如果属于同真同假,则判断是否二者已处于一真一假的状态,如果是则集合加入失败,反之将\((i,j)\)与\((i+n,j+n)\)加入同一集合
  • 如果属于一真一假,则判断是否二者已处于同真同假的状态,如果是则集合加入失败,反之将\((i,j+n)\)与\((i+n,j)\)加入同一集合

最后统计答案时,考虑遍历所有人,如果未加入答案集合中,则添加\(\max\{sz_{撒谎者},sz_{诚实的人}\}\),并将其本身与连带关系加入答案集合

注意:

由于已有关系仍然可能出现,而在建立过程中更改了\(sz\)数组,所以此时要对建立关系的步骤进行忽略

#include<cstdio>
#include<algorithm>
using namespace std;
int n, m;
const int maxn = 4e5 + 5;
int p[maxn], sz[maxn]; int find(int x) {
if (p[x] == x) return x;
return p[x] = find(p[x]);
} bool set2(int x, int y) {
int x1 = find(x), x2 = find(y), y1 = find(x + n), y2 = find(y + n);
if (x1 == x2) return false;
if (x1 == y2 || x2 == y1) return true;
sz[x1] += sz[y2];
sz[y1] += sz[x2];
p[y2] = x1;
p[x2] = y1;
return true;
} bool set1(int x, int y) {
int x1 = find(x), x2 = find(y), y1 = find(x + n), y2 = find(y + n);
if (x1 == y2 || x2 == y1) return false;
if (x1 == x2) return true;
sz[x1] += sz[x2];
sz[y1] += sz[y2];
p[x2] = x1;
p[y2] = y1;
return true;
} char str[1000];
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
for (int i = 0; i <= n; ++i)
sz[i] = 0, p[i] = i;
for (int i = n + 1; i <= 2 * n; ++i)
sz[i] = 1, p[i] = i;
int a, b;
bool ok = true;
while (m--) {
scanf("%d%d%s", &a, &b, str);
if (str[0] == 'i')
ok &= set2(a, b);
else ok &= set1(a, b);
}
for (int i = 1; i <= n; ++i)
if (find(i) && find(i + n)) {
sz[0] += max(sz[find(i)], sz[find(i + n)]);
p[find(i)] = p[find(i + n)] = 0;
}
if (ok)
printf("%d", sz[0]);
else
printf("-1");
printf("\n");
}
}

E hard version(搜索+状态转移+组合)

题目链接

题目:

给出一个高度为\(k\)的满二叉树,编号按层次遍历,现要给每个节点染色,其中相邻节点不能均为(红、橙)(白、黄)(绿、蓝)三对中某一对,且有些节点色彩已被指定,问染色方案数

解析:

根据Easy Version的结论,对于每个节点来说,如果父节点颜色已被确定,则该节点有4种方案,所以当某些节点(假设总个数未\(cnt_{else}\))未被指定颜色节点影响时,贡献为\(4^{cnt_{else}}\)

对于那些被影响的节点,考虑使用\(map\)存储每个节点的颜色属于的对,并且对他的所有父节点进行标记(被影响),\(cnt_{else}=2^k-1-map_{size}\),考虑进行搜索(假设\(v[0,1,2]\)分别代表当前节点取某个颜色对中的颜色时,可行的方案数)不难得到以下转移式

\[\text{init} :v=\{2,2,2\}\ or\ \{x_0,x_1,x_2\}\ \text{x is depend on its color}\\
v[0]=v[0]*(v_{son}[1]+v_{son}[2]) \\
v[1]=v[1]*(v_{son}[0]+v_{son}[2]) \\
v[2]=v[2]*(v_{son}[0]+v_{son}[1])
\]

最后答案即为\((v_1[0]+v_1[1]+v_1[2])\times 4^{cnt_{else}}\)

注意:

博主也不知道为什么,这里使用\(map\)可以AC,但使用\(unordered_map\)会TLE在第9个样例(若有同学知晓,可否评论区指点一二)

#include<bits/stdc++.h>
using namespace std; const int maxn = 3e5 + 5;
char str[maxn]; map<long long, int> m;
int k, n;
const long long mod = 1e9 + 7; long long ksm(long long a, long long b) {
long long ans = 1;
while (b) {
if (b & 1) ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans;
} vector<long long> dfs(long long x) {
vector<long long> t = { 2,2,2 };
if (m.count(x) && ~m[x]) {
for (int i = 0; i < 3; ++i)
t[i] = i == m[x];
}
for (long long i : {x << 1, x << 1 | 1}) {
if (!m.count(i)) continue;
vector<long long> s = dfs(i);
t[0] = (t[0] * (s[1] + s[2]) % mod) % mod;
t[1] = (t[1] * (s[0] + s[2]) % mod) % mod;
t[2] = (t[2] * (s[0] + s[1]) % mod) % mod;
}
//printf("%lld:%lld %lld %lld\n", x, t[0], t[1], t[2]);
return t;
} int main() {
long long v;
char ch;
scanf("%d%d", &k, &n);
while (n--) {
scanf("%lld %c%*s", &v, &ch);
switch (ch) {
case 'r':
case 'o': m[v] = 0; break;
case 'w':
case 'y': m[v] = 1; break;
default: m[v] = 2;
}
v >>= 1;
while (v) {
if (!m.count(v))
m[v] = -1;
else break;
v >>= 1;
}
}
vector<long long> ans = dfs(1);
printf("%lld", (ans[0] + ans[1] + ans[2]) % mod * ksm(4, (1ll << k) - 1 - m.size()) % mod);
}

F(构造)

题目链接

题目:

将\(s\)个物品分为\(n\)堆,每堆编号从\(1\sim n\),且保证每堆至少有一个物品,问是否对于任意一种物品分发方式都存在一个连续区间\([l,r]\)使得,这段区间内对应堆中物品数量和为\(k\)

解析:

当\(s=k\)时,即每次取所有堆的情况,显然成立

当\(s<k\)时,取所有物品也到不了\(k\),显然不成立

对于\(s>k\)的情况,考虑构造一个所用物品最小,且不满足条件的分配方式

\[\underbrace{1, 1, 1, \dots}_{k-1},\ k+1,\ \underbrace{1,1,1,\dots}_{k-1},\ k+1,\ \dots
\]

不难发现这样的构造方式下,需要对每个堆分发一个物品,剩下的物品数量为\(s-n\),而下标为\(k\)的倍数的位置,需要再多分配\(k\)个物品,总计为\(\lfloor \frac{n}{k}\rfloor k\)个物品,那么当\(s-n<\lfloor \frac{n}{k}\rfloor k\)时无法构造

#include<bits/stdc++.h>
using namespace std; int main() {
int T;
long long s, n, k;
scanf("%d", &T);
while (T--) {
scanf("%lld%lld%lld", &s, &n, &k);
if (s == k) printf("YES\n");
else if (s < k) printf("NO\n");
else printf("%s\n", n / k * k > s - n ? "YES" : "NO");
}
}

Codeforces Round #747 (Div. 2)的更多相关文章

  1. Codeforces Round #747 (Div. 2) Editorial

    Codeforces Round #747 (Div. 2) A. Consecutive Sum Riddle 思路分析: 一开始想起了那个公式\(l + (l + 1) + - + (r − 1) ...

  2. Codeforces Round #747 (Div. 2)题解

    谢天谢地,还好没掉分,还加了8分,(8分再小也是加啊)前期刚开始有点卡,不过在尽力的调整状态之后,还是顺利的将前面的水题过完了,剩下的E2和F题就过不去了,估计是能力问题,自己还是得认真补题啦. E2 ...

  3. 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 ...

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

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

  5. Codeforces Round #368 (Div. 2)

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

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

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

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

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

  8. 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 ...

  9. 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 ...

随机推荐

  1. Spark消费Kafka如何实现精准一次性消费?

    1.定义 精确一次消费(Exactly-once) 是指消息一定会被处理且只会被处理一次.不多不少就一次处理. 如果达不到精确一次消费,可能会达到另外两种情况: 至少一次消费(at least onc ...

  2. super的两个作用

    super与实例没有什么关系,它本身有两个作用的,参考如下理解: 1.super可以当函数用.super作为函数调用时,表示父类的构造函数.示例: class Par { constructor() ...

  3. promise小案例

    页面中有个板块,需要多张图片加载完之后才能进行显示 //页面中有个板块 需要多张图片加载完之后才能进行显示 const loadImg = (src) => { return new Promi ...

  4. Ubuntu 设置不更新某些软件

    方法来自:https://blog.csdn.net/zhrq95/article/details/79527073 保持某软件版本不变,如我wps-office,(已测有效@Ubuntu 16.04 ...

  5. Error establishing a database connection!

    后来发现在 wp-config.php 有个 debug 的参数,打开这个参数,修改为: define('WP_DEBUG','true'); 修改这个后,非常不错,报了很多错,一堆....   使用 ...

  6. MySQL存储结构及SQL分类

    MySQL目录结构 bin -- mysql执行程序 docs -- 文档 share - 各国编码信息 data -- 存放mysql 数据文件 * 每个数据库 创建一个同名文件夹,.frm 存放t ...

  7. thrift的介绍及其使用

    什么是thrift Thrift是Facebook于2007年开发的跨语言的rpc服框架,提供多语言的编译功能,并提供多种服务器工作模式:用户通过Thrift的IDL(接口定义语言)来描述接口函数及数 ...

  8. 学习Linux tar 命令:最简单也最困难

    摘要:在本文中,您将学习与tar 命令一起使用的最常用标志.如何创建和提取 tar 存档以及如何创建和提取 gzip 压缩的 tar 存档. 本文分享自华为云社区<Linux 中的 Tar 命令 ...

  9. WebService学习总结(五)--CXF的拦截器

    拦截器是Cxf的基础,Cxf中很多的功能都是由内置的拦截器来实现的,拦截器在Cxf中由Interceptor表示.拦截器的作用类似axis2中handle.Cxf的拦截器包括入拦截器和出拦截器,所有的 ...

  10. Redis的持久化机制与内存管理机制

    1.概述 Redis的持久化机制有两种:RDB 和 AOF ,这两种机制有什么区别?正式环境应该采用哪种机制? 我们的服务器内存资源是有限的,如果内存被Redis的缓存占满了怎么办?这就要看Redis ...