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. Android开发之漫漫长途 XIV——RecyclerView

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  2. docker dead but pid file exists

    CentOS 6安装docker 报docker dead but pid file exists 执行 yum install epel-release yum install docker-io ...

  3. 日均数据量千万级,MySQL、TiDB两种存储方案的落地对比

    http://mp.weixin.qq.com/s?__biz=MzIzNjUxMzk2NQ==&mid=2247484743&idx=1&sn=04337e020d268a9 ...

  4. 在tableViewCell的点击事件中处理界面跳转问题

    UIViewController *controller; UIView *view = self.view; while (1) { controller = (UIViewController * ...

  5. 基于Centos7的autobahn-python+crossbar的环境搭建

    一.基于centos7的crossbar安装(已经安装好python) (1) sudo yum update (2) sudo yum install gcc gcc-c++ make openss ...

  6. Python 判断闰年,判断日期是当前年的第几天

    http://www.cnblogs.com/vamei/archive/2012/07/19/2600135.html Python小题目 针对快速教程 作业答案 写一个程序,判断2008年是否是闰 ...

  7. js利用闭包封装自定义模块的几种方法

    1.自定义模块: 具有特定功能的js文件 将所有的数据和功能都封装在一个函数的内部 只向外暴露一个包含有n个方法的对象或者函数 模块使用者只需要通过模块暴露的对象调用方法来实现相对应的功能 1.利用函 ...

  8. Py4j-RPC

    python 使用灵活.方便在科研中被广泛的使用,Numpy和SciPy等科学计算库使其拥有强大的计算方式.很多机器学习和深度学习的库也都采用了python,然而在大数据.后台开发中仍然较多的使用Ja ...

  9. Phpstrom操作git

    1.PHPstrom操作git[上传] 2.提交代码到仓库 2. 3.使用git bash上传代码仓库的代码到远程服务器 代开git bash进入到项目所在的目录,输入命令$  git push .上 ...

  10. JAVA的helloworld

    java环境设置------------- 在环境变量中设置以下三个变量:JAVA_HOME=C:\j2sdk1.4.1 //可以改为相应的目录CLASSPATH=%JAVA_HOME%\lib\to ...