当前位置: 代码迷 >> 综合 >> Educational Codeforces Round 37 (Rated for Div. 2)
  详细解决方案

Educational Codeforces Round 37 (Rated for Div. 2)

热度:94   发布时间:2023-10-29 09:13:48.0

前言

昨晚打了一场CF,战绩不太好,只写了ABCFG,赛后更正了E
在这里写一下题解

A

二分答案,直接判断

B

直接模拟即可

C

考虑到连续一段1里面事可以互换的,暴力扫一次即可

D

没做

E

题意:给你一个完全图,删去若干跳变,询问有多少个联通块
思路比较好的一道题,考试的时候没有想出来
对于每一个点,扫所有点,如果它们之间有边,就合并成一个联通快
扫的时候就扫没有合并的点
考虑到每一次合并,点数会少1,所以这个过程是O(n)的
然后再考虑点数不会边的情况,就是有边,这个过程是O(m)的
于是总体复杂度是O(n+m)的
CODE:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=200005;
int n,m;
vector<int> e[N];
int f[N];//并查集
bool vis[N];
int cnt;
vector<int> ans[N];
int find (int x){
   return f[x]==x?x:f[x]=find(f[x]);}
void dfs (int x)
{/*printf("%d\n",x);system("pause");*/vis[x]=true;ans[cnt].push_back(x);f[x]=x+1;int i=0;for (int u=find(1);u<=n;u=find(u+1)){while (i<e[x].size()&&e[x][i]<u) i++;if (i<e[x].size()&&e[x][i]==u) continue;dfs(u);}
}
int lalal[N];
int main()
{scanf("%d%d",&n,&m);for (int u=1;u<=m;u++){int x,y;scanf("%d%d",&x,&y);e[x].push_back(y);e[y].push_back(x);}for (int u=1;u<=n;u++) sort(e[u].begin(),e[u].end());memset(vis,false,sizeof(vis));for (int u=1;u<=n+1;u++) f[u]=u;for (int u=1;u<=n;u++)if (!vis[u]){cnt++;dfs(u);}printf("%d\n",cnt);for (int u=1;u<=cnt;u++)lalal[u]=ans[u].size();sort(lalal+1,lalal+1+cnt);for (int u=1;u<=cnt;u++)printf("%d ",lalal[u]);return 0;
}

F

这题的话,先线性筛出所有数的约数个数
然后考虑到,一个数n的约数个数是不超过n??n
所以修改的次数不会很多,就5,6次左右
变到2,1就不会变了
再线段树上打标记即可

G

先分解质因数
二分答案,然后容斥得到个数就可以了

  相关解决方案