Educational Codeforces Round 37

这场有点炸,题目比较水,但只做了3题QAQ。还是实力不够啊!

写下题解算了……(写的比较粗糙,细节或者bug可以私聊2333)


A. Water The Garden

题意

给你一个长度为\(n\)的池子,告诉你哪些地方一开始有水,每秒可以向左和向右增加一格的水,问什么时候全部充满水。(\(n \le 200\))

题解

按题意模拟。每次进来一个水龙头,就更新所有点的答案(取\(min\))。最后把所有点取个\(max\)就可以了。


B. Tea Queue

题意

有\(n\)个人来喝咖啡。咖啡店每个时刻只能有一个人在喝咖啡。第\(i\)个人有进来的时间\(l_i\)和离开的时间\(r_i\),这意味着他会在\(l_i\)时间来排队,如果到\(r_i\)的时候还没喝到咖啡,他就会离开队列。

同时有多个人来排的话,编号小的在前面。问每个人最早喝到咖啡的时间,如果不能喝到就输出\(0\)。

(\(n \le 1000 \ \ l_i,r_i \le 5000\)) 输入数据已经按照\(l_i\)非降序排列。有\(T\)组数据。(\(T \le 1000\))

题解

又是一个模拟...我没有用队列去写,而用一个\(set\)去模拟这个队列。定义一个pair<int, int> set S,第一关键字是他进来的时间,第二关键字是他的编号,每秒取S.begin()就行了。中间删除也很好用。


C. Swap Adjacent Elements

题意

给你一个长度为\(n\)的排列,然后告诉你一些位置(这些位置相邻)能进行交换,判断是否能将原序列变得有序。(\(n \le 200000\))

题解

考虑一个分组,将这个段分成很多子段。这些段内部可以相互任意交换,所以这种段就直接能排好序。然后我们就可以对于每段check一下,看它(这个段)是否本身就是在这个位置上。

即这个段为\([l,r]\)时,\(\forall i \in [l,r]\) 满足\(a_i \in [l,r]\)。这是因为段与段之间不可能有互换的操作,所以是相对独立的子段,本身位置不会有任何变动。


D. Tanks

  • 这题我没看,也没做QAQ,似乎是一道构造?还是dp?全场A的最少的。。不想改了(绝对不是因为我懒,而是因为我菜2333)。

yyb过了Orz


E. Connected Components?

题意

给你一个有\(n\)个点的无向完全图,然后在里面删除\(m\)条边,求联通块数量和联通块大小。(\(n,m \le 200000\))

题解

这个题就是个暴力优化……考虑一开始先找出大的联通块,然后不难想到按照点的度数从大到小进行排序。然后我们再维护一个剩余点集。

每次Dfs一个点,再枚举点集中的点,看是否连边。(一开始程序过了system test 后来被hack了QAQ 只是因为有些没搞到一起来)时间复杂度我不会分析QAQ……

但是第一次总能带走特别多的点,使得这个集合不是很大。

代码

#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), _end_ = (int)(r); i <= _end_; ++i)
#define Fordown(i, r, l) for(register int i = (r), _end_ = (int)(l); i >= _end_; --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std; bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;} inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar() ) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ '0');
return x * fh;
} void File() {
#ifdef zjp_shadow
freopen ("e.in", "r", stdin);
freopen ("e.out", "w", stdout);
#endif
} const int N = 200100;
int n, m;
struct point {
int deg, no;
bool operator < (const point &rhs) const {return deg > rhs.deg; }
};
point lt[N]; vector<int> ans;
int res = 0; int L[N], R[N];
set<int> Ban[N]; int fa[N];
int find(int x) {
return fa[x] == x ? x : (fa[x] = find(fa[x]) );
} int sum[N]; bool vis[N]; inline void Delete(int x) {
vis[x] = true;
L[R[x]] = L[x];
R[L[x]] = R[x];
} inline void Connect(int a, int b) {
int r1 = find(a), r2 = find(b);
if (r1 == r2) return ;
fa[r1] = r2;
} int Col[N]; void Dfs(int u) {
vector<int> Go;
for (register int v = R[0]; v <= n; v = R[v])
if (!vis[v] && Ban[u].find(v) == Ban[u].end() ) Connect(u, v), Delete(v), Go.push_back(v);
for (register auto v : Go) Dfs(v);
} int main () {
File();
cin >> n >> m;
For (i, 1, n)
lt[i].no = i, lt[i].deg = n - 1; For (i, 1, m) {
int u = read(), v = read();
Ban[v].insert(u);
Ban[u].insert(v);
--lt[u].deg; --lt[v].deg;
} R[0] = 1;
For (i, 1, n) L[i] = i - 1, R[i] = i + 1; sort (lt + 1, lt + 1 + n);
For (i, 1, n) fa[i] = i;
For (i, 1, n)
if (!vis[lt[i].no]) Delete(lt[i].no), Dfs(lt[i].no); For (i, 1, n) ++ sum[find(i)];
For (i, 1, n) if (sum[i]) ans.push_back(sum[i]); sort (ans.begin(), ans.end() );
cout << ans.size() << endl;
for (auto i : ans)
printf ("%d ", i);
return 0;
}

F. SUM and REPLACE

题意

给你一个长为\(n\)的序列,每个数为\(a_i\)。共有\(m\)个操作,分为两种类别。第一种就是对于一个区间\([l,r]\)中的所有数变为它们约数个数的数,第二种就是求区间\([l,r]\)的和。(\(n,m \le 3 \cdot 10^5 \ \ a_i \le 10^6\))

题解

这和之前两道题十分类似,一个是开方,一个是除以2。不难发现这些操作有效次数特别少。我用暴力筛,筛的约数个数,然后发现在\(10^6\)范围内最多操作6次。

然后可以直接裸一个线段树上去,支持单点修改和区间查询。

代码

#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), _end_ = (int)(r); i <= _end_; ++i)
#define Fordown(i, r, l) for(register int i = (r), _end_ = (int)(l); i >= _end_; --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std; bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;} inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar() ) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ '0');
return x * fh;
} void File() {
#ifdef zjp_shadow
freopen ("f.in", "r", stdin);
freopen ("f.out", "w", stdout);
#endif
} const int N = 1e6 + 1e3;
int n, m;
int d[N]; void Init(int maxn) {
For (i, 1, maxn)
for (register int j = i; j <= maxn; j += i) ++ d[j];
} int maxv[N << 2], sumv[N << 2]; #define lson o << 1, l, mid
#define rson o << 1 | 1, mid + 1, r
inline void push_up(int o) {
maxv[o] = max(maxv[o << 1], maxv[o << 1 | 1]);
sumv[o] = sumv[o << 1] + sumv[o << 1 | 1];
} void Build(int o, int l, int r) {
if (l == r) {maxv[o] = sumv[o] = read(); return ;}
int mid = (l + r) >> 1; Build(lson); Build(rson); push_up(o);
} int ul, ur; void Update(int o, int l, int r) {
if (maxv[o] <= 2) return ;
if (l == r) { maxv[o] = d[maxv[o]]; sumv[o] = d[sumv[o]]; return ; }
int mid = (l + r) >> 1;
if (ul <= mid) Update(lson);
if (ur > mid) Update(rson); push_up(o);
} int ql, qr;
int Query(int o, int l, int r) {
if (ql <= l && r <= qr) return sumv[o];
int mid = (l + r) >> 1, res = 0;
if (ql <= mid) res += Query(lson);
if (qr > mid) res += Query(rson); return res;
} int main () {
File();
Init((int)1e6);
n = read(); m = read();
Build(1, 1, n);
For (i, 1, m) {
int opt = read();
if (opt == 1) {
ul = read(); ur = read();
Update(1, 1, n);
} else {
ql = read(); qr = read();
printf ("%d\n", Query(1, 1, n) );
}
}
return 0;
}

G. List Of Integers

题意

给你三个整数\(x\),\(p\),\(k\)。求满足条件\(y > x\)且\(gcd(y,p)=1\)的第\(k\)个\(y\)。

(\(x,p,k \le 10^6\))

题解

一开始看错题,以为直接给你\(y\)求和,直接上莫比乌斯反演就行了。

但没关系,不难发现可以二分这个\(y\)。只要满足\(sum_y-sum_x \ge k\) 的第一个就行了,此处的\(sum_q\) 就是 \(\sum \limits _{i=1}^{q} [gcd(i,p)=1]\)。

我们简单化一下式子。

\[\sum \limits _{i=1}^{q} [gcd(i,p)=1]
\]

\[=\sum \limits _{i=1}^{q} \sum \limits_{d | gcd(i,p)} \mu(d)
\]

\[=\sum \limits _{d|p} \mu(d) \cdot \lfloor \frac {q}{d} \rfloor
\]

我们可以在\(O(\sqrt{p})\)的时间内求出\(p\)所有约数

(大约有\(p^{1/3}\)个)。然后就可以直接求了。

总时间复杂度为\(O(T (\log 2e9 \cdot p^{1/3} + \sqrt p))\)。

那个\(2e9\)是因为我不知道右边界有多大啊QAQ,随便取的,取小会WA。

代码

#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), _end_ = (int)(r); i <= _end_; ++i)
#define Fordown(i, r, l) for(register int i = (r), _end_ = (int)(l); i >= _end_; --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std; bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;} inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar() ) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ '0');
return x * fh;
} int x, p, k; const int N = 1e6 + 1e3;
int mu[N], prime[N], cnt;
int fac[N];
bitset<N> is_prime; void Init(int maxn) {
is_prime.set();
int res;
is_prime[0] = is_prime[1] = false;
mu[1] = 1;
For (i, 2, maxn) {
if (is_prime[i]) {
prime[++cnt] = i; mu[i] = -1; fac[i] = i;
}
For (j, 1, cnt) {
res = prime[j] * i;
if (res > maxn) break ;
is_prime[res] = false;
if (!fac[res]) fac[res] = prime[j];
if (i % prime[j]) mu[res] = -mu[i];
else { mu[res] = 0; break; }
}
}
} vector<int> V;
bool have[N]; inline void Resolve() {
V.clear();
For (i, 1, sqrt(p) ) if (!(p % i) ) {
V.push_back(i);
if (i * i != p) V.push_back(p / i);
}
} inline int Calc(int maxn) {
int res = 0; for (auto i : V) res += mu[i] * (maxn / i);
return res;
} int main () {
int cases = read();
Init((int)1e6);
while (cases --) {
x = read(); p = read(); k = read();
Resolve();
int res1 = Calc(x), res2;
int l = x, r = 1e9; int ans;
while (l <= r) {
int mid = (l + r) >> 1;
res2 = Calc(mid);
if (res2 - res1 >= k) {
ans = mid;
r = mid - 1;
} else l = mid + 1;
}
cout << ans << endl;
}
return 0;
}

ps:yyb 把我吊起来打 Orz

Educational Codeforces Round 37的更多相关文章

  1. Educational Codeforces Round 37 (Rated for Div. 2)C. Swap Adjacent Elements (思维,前缀和)

    Educational Codeforces Round 37 (Rated for Div. 2)C. Swap Adjacent Elements time limit per test 1 se ...

  2. Educational Codeforces Round 37 G. List Of Integers (二分,容斥定律,数论)

    G. List Of Integers time limit per test 5 seconds memory limit per test 256 megabytes input standard ...

  3. codeforces 920 EFG 题解合集 ( Educational Codeforces Round 37 )

    E. Connected Components? time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  4. Educational Codeforces Round 37 (Rated for Div. 2) 920E E. Connected Components?

    题 OvO http://codeforces.com/contest/920/problem/E 解 模拟一遍…… 1.首先把所有数放到一个集合 s 中,并创建一个队列 que 2.然后每次随便取一 ...

  5. Educational Codeforces Round 37 E. Connected Components?(图论)

    E. Connected Components? time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  6. 【Educational Codeforces Round 37】F. SUM and REPLACE 线段树+线性筛

    题意 给定序列$a_n$,每次将$[L,R]$区间内的数$a_i$替换为$d(a_i)$,或者询问区间和 这题和区间开方有相同的操作 对于$a_i \in (1,10^6)$,$10$次$d(a_i) ...

  7. Educational Codeforces Round 37 A B C D E F

    A. water the garden Code #include <bits/stdc++.h> #define maxn 210 using namespace std; typede ...

  8. Educational Codeforces Round 37 (Rated for Div. 2)

    我的代码应该不会被hack,立个flag A. Water The Garden time limit per test 1 second memory limit per test 256 mega ...

  9. Educational Codeforces Round 37 (Rated for Div. 2) G

    G. List Of Integers time limit per test 5 seconds memory limit per test 256 megabytes input standard ...

随机推荐

  1. sql的升阶

    前言:基本数据库操作根本无法满足实际的需要,需要引入更多的操作. 触发器-隐式的,主动的,更新数据表中的信息.带有inserted和deleted两个临时表,代表新操作和旧操作. 它是一种特殊的存储过 ...

  2. RabbitMQ 简单测试

    RabbitMQ 测试 RabbitMQ 基于Erlang 实现, 客户端可以用Python | Java | Ruby | PHP | C# | Javascript | Go等语言来实现.这里做个 ...

  3. Nginx Rewrite规则详解

    Rewrite规则含义就是某个URL重写成特定的URL,从某种意义上说为了美观或者对搜索引擎友好,提高收录量及排名等. Rewrite规则的最后一项参数为flag标记,支持的flag标记主要有以下几种 ...

  4. 940B Our Tanya is Crying Out Loud

    传送门 题目大意 给你n,k,A,B四个数,x=n,有两种操作: 1.将x-1,需支付A个金币 2.将x÷k,需支付B个金币,当且仅当k能整除x时可进行此操作 问将x修改为1至少要花几个金币 分析 模 ...

  5. img alt与title的区别

    前端 alt是图片加载不出来时候,对图片的文本替代 title 是鼠标放在图片上时,对图片的进一步说明 seo 搜索引擎对图片意思的理解主要靠 alt

  6. Sql Server 常用事务处理总结

    在数据库操作中,常用事务写法: 1. 通过 @@error 判断一批sql 执行完毕,是否有异常.  @@error 为系统变量,每次执行完 sql 都会返回一个数值,  0 表示 执行成功 ,非0 ...

  7. Windows下nexus-3.*搭建Maven私服

    1.下载 从官网下载https://help.sonatype.com/display/NXRM3/Download 选择Windows archive https://download.sonaty ...

  8. Acm弱校奋斗史

    我也是来自弱校的,没有教练,甚至老师都不理我们这种Acmer.看完这篇文章感触颇深. 原文链接 http://acmicpc.info/archives/369 原文 题解:还记得2年前的一个晚上,我 ...

  9. 自动化测试 selenium中WebDriver 和WebElement的区别

    之前在做UI自动化测试中 经常会用到  WebDriver  和 WebElement两个类   以前对这两个类总感觉有点傻傻分不清 昨天看了下之前下的代码  结合自己的理解  对着两个类的区别和关系 ...

  10. Java并发编程-线程可见性&线程封闭&指令重排序

    一.指令重排序 例子如下: public class Visibility1 { public static boolean ready; public static int number; } pu ...