CodeForces round 520 div2
A:A Prank
题意:给定一个递增序列, 问最多能删除多少个连续数字,要求删除数字之后能还原成原来的数列。
题解:直接找就好了,为了方便可以使得第0个数字为0, 第n+1个元素为1001
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
int a[N];
int main(){
int n, m = ;
scanf("%d", &n);
a[] = , a[n+] = ;
for(int i = ; i <= n; ++i) scanf("%d", &a[i]);
int ans = ;
for(int i = ; i <= n; ++i){
if(a[i-]+ == a[i] && a[i]+ == a[i+]) m++;
else m = ;
ans = max(ans, m);
}
cout << ans << endl;
return ;
}
B:Math
题意:给你一个n,现在有2种操作,1把这个n乘上一个值,2把这个n开根号,要求开完根号之后还是整数,求n最小能变成多少,以及最小的操作次数。
题解:对于一个数字,我们先把他分解质因子,计算每个因子的个数,很明白,只有所有的质因子都为偶数的时候,他这个时候才能开方,
并且,这个数的最小值就是这些不同的质因子的乘积。
要使数字变小,所以我们先需要把每个因子的个数都变成偶数,然后在开根号,因子个数都会/2
所以我们需要找到最大的因子个数是啥,假如为x,然后把所有数目都变成 x <= 2^k 次,然后我们只需要一直开方就好了。
如果x = 5, 我们至少要把除3次,为了避免每次都需要先乘上一个数,我们把第一次乘法的时候就把他变成2^k。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
vector<int> vc;
int aaans = ;
void solve(int x){
for(int i = ; i*i <= x; ++i){
if(x%i == ){
int cnt = ;
aaans *= i;
while(x%i == ){
x /= i;
cnt++;
}
vc.pb(cnt);
}
}
if(x != ) vc.pb();
aaans *= x;
}
int cnt = ; int main(){
int n;
scanf("%d", &n);
solve(n);
if(vc.size() == ) vc.pb();
int mx = , f = ;
for(auto v : vc){
mx = max(v, mx);
}
int tmp = ;
for(int i = ;;++i){
if(mx <= (<<i)){
tmp = i;
break;
}
}
int ans = tmp;
tmp = << tmp;
for(auto v: vc){
if(tmp != v) f = ;
}
ans += f;
cout << aaans << ' ' << ans << endl;
return ;
}
C:Banh-mi
题解:找规律。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
int cnt[N][];
LL dp[N];
void init(){
//LL t = 1;
dp[] = ;
for(int i = ; i < N; ++i){
dp[i] = dp[i-]<<;
if(dp[i] > mod) dp[i] -= mod;
}
}
int solve(int x, int y){
LL ret = ;
ret = dp[y+] - ;
ret += (dp[y+]-)*(dp[x+]-);
ret = ((ret%mod)+mod)%mod;
return ret;
}
char s[N];
int main(){
int n, q;
init();
scanf("%d%d", &n, &q);
scanf("%s", s+);
for(int i = ; i <= n; ++i){
cnt[i][] = cnt[i-][];
cnt[i][] = cnt[i-][];
cnt[i][s[i]-'']++;
}
int l, r;
while(q--){
scanf("%d%d", &l, &r);
printf("%d\n", solve(cnt[r][]-cnt[l-][],cnt[r][]-cnt[l-][]));
}
return ;
}
题解:我们可以从样例分析中发现,我们可以经过4次跳跃之后返回到原来的这个地方。
也就是说,我们每次走到一个新的位置之后,我们可以遍历他的所有因子,再返回到这个位置,然后继续按原来的路径行事。
我们不用管他怎么走,只需要明白每出现一个数会对答案产生什么影响就好了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
int vis[N];
void init(){
for(int i = ; i < N; ++i){
for(int j = i+i, t = ; j < N; j+=i, t++){
vis[j] += t;
}
}
}
int main(){
int n;
scanf("%d", &n);
init();
LL sum = ;
for(int i = ; i <= n; ++i){
sum += vis[i];
}
cout << sum* << endl;
return ;
}
E:Company
题意:求多个点 在可以删除一个点的前提下剩下的点lca 取 深度最大的点能是啥。
题解:我们把树建立起来,跑一遍dfs,记录下他的dfs序。
那么答案就是找到这个区间的 最大值dfs序, 次大值, 次小值, 最小值。
然后答案就是在删除最大值的位置下 和 删除最小值的位置下取优。
这个操作是基于一个思想,就是 这些点的lca就是 dfs序的最大值的那个位置 和 最小值的那个位置的lca。
原因很简单,我们需要找到一个点 他的dfs序 入和出 能包括询问的所有的dfs序。
也就是说找到一个点 in[v] <= min(q - point ) out[v] >= max( q - point)
观察上式,我们发现只有 最大值和最小值发生了改变才会对答案产生影响, 删除中间的点是不会产生影响的。
所以我们只需要找到 最大值, 次大值, 次小值, 最小值 然后删除最大值 查询最小值和次大值的lca 和 删除最小值查询次小值和最大值的lca 2者取优就好了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
int anc[N][];
int dfn[N], now = , deep[N], pos[N];
int n, q;
vector<int> vc[N];
void dfs(int u){
dfn[u] = ++now;
pos[now] = u;
for(auto v : vc[u]){
deep[v] = deep[u] + ;
anc[v][] = u;
for(int i = ; i < ; ++i) anc[v][i] = anc[anc[v][i-]][i-];
dfs(v);
}
}
int Find(int u, int v){
if(deep[u] < deep[v]) swap(u,v);
int x = deep[u] - deep[v];
for(int i = ; i >= ; --i)
if((x>>i)&)
u = anc[u][i];
if(u == v) return u;
for(int i = ; i >= ; --i)
if(anc[u][i] != anc[v][i])
u = anc[u][i], v = anc[v][i];
return anc[v][]; }
int tmx[N<<], tmn[N<<];
void build(int l, int r, int rt){
if(l == r){
tmx[rt] = tmn[rt] = dfn[l];
return ;
}
int m = l+r >> ;
build(lson); build(rson);
tmx[rt] = max(tmx[rt<<], tmx[rt<<|]);
tmn[rt] = min(tmn[rt<<], tmn[rt<<|]);
}
int Qmax(int L, int R, int l, int r, int rt){
if(L > R) return ;
if(L <= l && r <= R) return tmx[rt];
int m = l+r >> ;
int ret = ;
if(L <= m) ret = max(ret, Qmax(L,R,lson));
if(m < R) ret = max(ret, Qmax(L,R,rson));
return ret;
}
int Qmin(int L, int R, int l, int r, int rt){
if(L > R) return N;
if(L <= l && r <= R) return tmn[rt];
int m = l+r >> ;
int ret = N;
if(L <= m) ret = min(ret, Qmin(L,R,lson));
if(m < R) ret = min(ret, Qmin(L,R,rson));
return ret;
}
void solve(int l, int r){
int x1, x2, x3, x4;
int v1, v2, v3, v4;
v1 = Qmax(l,r,,n,);
x1 = pos[v1];
v2 = max(Qmax(l,x1-,,n,), Qmax(x1+,r,,n,));
x2 = pos[v2];
v4 = Qmin(l,r,,n,);
x4 = pos[v4];
v3 = min(Qmin(l,x4-,,n,), Qmin(x4+,r,,n,));
x3 = pos[v3];
int ans1 = deep[Find(x1,x3)];
int ans2 = deep[Find(x2,x4)];
if(ans1 >= ans2)
printf("%d %d\n", x4, ans1);
else printf("%d %d\n", x1, ans2);
}
int main(){
scanf("%d%d", &n, &q);
for(int i = , u; i <= n; ++i){
scanf("%d", &u);
vc[u].pb(i);
}
dfs();
build(,n,);
int l, r;
while(q--){
scanf("%d%d", &l, &r);
solve(l, r);
}
return ;
}
题意:问有多少个点是合法点,u点如果是合法点,则最多只有一个点v 是 u没法走到v, v没法走到u。 题目说了一开始的图不会是强连通图。
题解:
我们先正向建图,然后按照拓扑排序的写法,当一个点的度数为0的时候入队。
每次我们取出一个点,我们看看队内是否为空,如果队内为空,则我们目前的这个点一定就是可以走到剩下图中所有的点。
如果队内还有一个点, 首先我们需要明白, 已经取出来的点x 和 还在队内的那个点y 这2个点之间是没有边的关系的,即 x 不能走到 y, y不能走到x。
现在我们判断一下,在剩下的图中,是不是有一个点是只能通过y走到的,如果存在这样的一个点,那么算上y之后就有2个点是x所不能走到了,那么x一定是非法点,所以我们不需要再精确的计算出x能到达多少点,这已经是没有意义的了。如果不存在一个点只能通过y走到,那么到目前为止,对于x来说只有y是没办法走到了,剩下图中的所有点都是可以走到的。
当队内不止有一个点之后,我们通过上面的分析可以明白,x一定不会是合法点,因为已经至少有2个点不行了,同样的我们也不再需要计算x可以到多少个点。
我们再反向建图,再按上面的程序跑一遍。
最后我们把v能达到的点的数目和能到达v点的数目加起来,就可以判断这个点是不是合法点了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 3e5 + ;
vector<int> vc[N];
int u[N], v[N], d[N];
int ans[N];
int n, m;
int sta[N];
void bfs(){
int tot = n;
int l = , r = ;
for(int i = ; i <= n; ++i)
if(d[i] == ){
sta[r++] = i;
tot--;
}
while(l < r){
int x = sta[l++];
if(l == r) ans[x] += tot;
else if(l+ == r){
int y = sta[l], f = ;
for(auto v : vc[y]){
if(d[v] == ){
f = ;
break;
}
}
if(f) ans[x] += tot;
}
for(auto v : vc[x]){
--d[v];
if(d[v] == ){
sta[r++] = v;
tot--;
}
}
} }
int main(){
scanf("%d%d", &n, &m);
for(int i = ; i <= m; ++i)
scanf("%d%d", &u[i], &v[i]);
for(int i = ; i <= m; i++){
vc[u[i]].pb(v[i]);
++d[v[i]];
}
bfs();
for(int i = ; i <= n; ++i)
vc[i].clear();
for(int i = ; i <= m; ++i){
vc[v[i]].pb(u[i]);
++d[u[i]];
}
bfs();
int fans = ;
for(int i = ; i <= n; ++i){
fans += (ans[i] >= n-);
}
printf("%d\n", fans);
return ;
}
CodeForces round 520 div2的更多相关文章
- Codeforces Round #539 div2
Codeforces Round #539 div2 abstract I 离散化三连 sort(pos.begin(), pos.end()); pos.erase(unique(pos.begin ...
- Codeforces Round #520 (Div. 2)
Codeforces Round #520 (Div. 2) https://codeforces.com/contest/1062 A #include<bits/stdc++.h> u ...
- 【前行】◇第3站◇ Codeforces Round #512 Div2
[第3站]Codeforces Round #512 Div2 第三题莫名卡半天……一堆细节没处理,改一个发现还有一个……然后就炸了,罚了一啪啦时间 Rating又掉了……但是没什么,比上一次好多了: ...
- Codeforces Round#320 Div2 解题报告
Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Fin ...
- Codeforces Round #564(div2)
Codeforces Round #564(div2) 本来以为是送分场,结果成了送命场. 菜是原罪 A SB题,上来读不懂题就交WA了一发,代码就不粘了 B 简单构造 很明显,\(n*n\)的矩阵可 ...
- Codeforces Round #361 div2
ProblemA(Codeforces Round 689A): 题意: 给一个手势, 问这个手势是否是唯一. 思路: 暴力, 模拟将这个手势上下左右移动一次看是否还在键盘上即可. 代码: #incl ...
- Codeforces Round #626 Div2 D,E
比赛链接: Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics) D.Present 题意: 给定大 ...
- CodeForces Round 192 Div2
This is the first time I took part in Codeforces Competition.The only felt is that my IQ was contemp ...
- Codeforces Round #359 div2
Problem_A(CodeForces 686A): 题意: \[ 有n个输入, +\space d_i代表冰淇淋数目增加d_i个, -\space d_i表示某个孩纸需要d_i个, 如果你现在手里 ...
随机推荐
- 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!
1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...
- 【Vue前端】Vue前端注册业务实现!!!【代码】
用户注册前端逻辑 1. Vue绑定注册界面准备 1.导入Vue.js库和ajax请求的库 <script type="text/javascript" src="{ ...
- StarUML 3.0 破解方法
首先在我这里下载 StarUML3.0 破解替换文件app.asar 链接:https://pan.baidu.com/s/1wDMKDQkKrE9D1c0YeXz0xg 密码:y65m 然后参照下 ...
- 关于dfs的套路
void dfs(答案, 搜索层数, 其他参数) { if (层数==maxdeep) { 更新答案 return; } (剪枝) for(下一层可能的状态){ 更新全局变量表示的状态的变量 dfs( ...
- Mybatis获取代理对象
mybatis-config.xml里标签可以放置多个environment,这里可以切换test和develop数据源 databaseIdProvider提供多种数据库,在xml映射文件里选择da ...
- Java实现ZooKeeper的zNode监控
上一篇文章已经完成了ZooKeeper的基本搭建和使用的介绍,现在开始用代码说话.参考 https://zookeeper.apache.org/doc/current/javaExample.htm ...
- javaScript基础-03 javascript语句
一. 声明语句 var和function都是声明语句.声明或定义变量或函数. var 声明一个或者多个变量.语法如下: var a ; var b = 1; var c, d; var e = 3; ...
- 帝国CMS(EmpireCMS) v7.5配置文件写入漏洞分析
帝国CMS(EmpireCMS) v7.5配置文件写入漏洞分析 一.漏洞描述 该漏洞是由于安装程序时没有对用户的输入做严格过滤,导致用户输入的可控参数被写入配置文件,造成任意代码执行漏洞. 二.漏洞复 ...
- 行车记+翻车记:.NET Core 新车改造,C# 节能降耗,docker swarm 重回赛道
非常抱歉,10:00~10:30 左右博客站点出现故障,给您带来麻烦了,请您谅解. 故障原因与博文中谈到的部署变更有关,但背后的问题变得非常复杂,复杂到我们都在怀疑与阿里云服务器 CPU 特性有关. ...
- 开发人员需要掌握的日常Linux命令集
本文整理了开发人员日常用到的linux相关命令,供参考. 文件相关 cd # 进入某个目录,不接参数进入当前用户目录(等同于cd ~)如/home/devuser,可接绝对路径或相对路径(../..表 ...