Codeforces Round #599 (Div. 2)

       久违的写篇博客吧

A. Maximum Square

题目链接:https://codeforces.com/contest/1243/problem/A

题意:

给定n个栅栏,对这n个栅栏进行任意排序,问可形成的最大正方形面积是多少

分析:

水题。

先排个序 , 然后暴力枚举正方形边长就可以了

#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define pd(n) printf("%d\n", (n))
#define pdd(n,m) printf("%d %d\n", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n,m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define mm(a,n) memset(a, n, sizeof(a))
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define ll long long
#define MOD 1000000007
#define pi 3.14159265358979323
#define lrt rt<<1
#define rrt rt<<1|1
#define lson l, m, lrt
#define rson m+1, r, rrt
#define debug(x)               cout << #x << ": " << x << endl
#define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
#define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
#define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
using namespace std;
const ll INF (0x3f3f3f3f3f3f3f3fll);
const int inf (0x3f3f3f3f);
template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
for(res=ch-48;isdigit(ch=getchar());res=(res<<1)+(res<<3)+ch - 48);flag&&(res=-res);}
template<typename T>void Out(T x){if(x<0)putchar('-'),x=-x;if(x>9)Out(x/10);putchar(x%10+'0');}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}
ll fact_pow(ll n,ll p){ll res=0;while(n){n/=p;res+=n;}return res;}
ll mult(ll a,ll b,ll p){a%=p;b%=p;ll r=0,v=a;while(b){if(b&1){r+=v;if(r>p)r-=p;}v<<=1;if(v>p)v-=p;b>>=1;}return r;}
ll quick_pow(ll a,ll b,ll p){ll r=1,v=a%p;while(b){if(b&1)r=mult(r,v,p);v=mult(v,v,p);b>>=1;}return r;}
bool CH(ll a,ll n,ll x,ll t)
{ll r=quick_pow(a,x,n);ll z=r;for(ll i=1;i<=t;i++){r=mult(r,r,n);if(r==1&&z!=1&&z!=n-1)return true;z=r;}return r!=1;}
bool Miller_Rabin(ll n)
{if(n<2)return false;if(n==2)return true;if(!(n&1))return false;ll x=n-1,t=0;while(!(x&1)){x>>=1;t++;}srand(time(NULL));
ll o=8;for(ll i=0;i<o;i++){ll a=rand()%(n-1)+1;if(CH(a,n,x,t))return false;}return true;}
int prime[30000010],minprime[30000010];
void euler(int n)
{int c=0,i,j;for(i=2;i<=n;i++){if(!minprime[i])prime[++c]=i,minprime[i]=i;for(j=1;j<=c&&i*prime[j]<=n;j++)
{minprime[i*prime[j]]=prime[j];if(i%prime[j]==0)break;}}}
 
const int N = 1e3 + 10;
int a[N];
int main(){
    ios;
    int t;
    cin >> t;
    while(t -- )
    {
        int n;
        cin >> n;
        int a[N];
        rep(i , 0 , n - 1)
        {
            cin >> a[i];
        }
        sort(a,a+n);
        int len = 0;
        per(i , n - 1 , 0)
        {
            if(a[i] > len){
                len ++;
            }
            else
            {
                break;
            }
        }
        cout << len << '\n';
    }
    return 0;
}
View Code

 

 

 

B1. Character Swap (Easy Version)

题目链接:https://codeforces.com/contest/1243/problem/B1

题意:

给你两个长度为 n 的字符串 S 和 T ,每次操作你可以交换 S 、T上任意两个位置的字符。问是否能只进行一次操作使 S 串 等于 T串。能输出 "Yes" , 不能输出 "No"

分析:

遍历字符串,当 S[i] != T[i] 时,判断从i + 1 到 n是否有s[j] == s[i] && t[j] != s[j],若不存在则说明无法进行一次操作使得两个字符串相等;

若存在则标记cot为0,继续遍历,倘若又一次出现s[i] != t[i],则输出"No".

#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define pd(n) printf("%d\n", (n))
#define pdd(n,m) printf("%d %d\n", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n,m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define mm(a,n) memset(a, n, sizeof(a))
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define ll long long
#define MOD 1000000007
#define pi 3.14159265358979323
#define lrt rt<<1
#define rrt rt<<1|1
#define lson l, m, lrt
#define rson m+1, r, rrt
#define debug(x)               cout << #x << ": " << x << endl
#define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
#define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
#define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
using namespace std;
const ll INF (0x3f3f3f3f3f3f3f3fll);
const int inf (0x3f3f3f3f);
template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
for(res=ch-48;isdigit(ch=getchar());res=(res<<1)+(res<<3)+ch - 48);flag&&(res=-res);}
template<typename T>void Out(T x){if(x<0)putchar('-'),x=-x;if(x>9)Out(x/10);putchar(x%10+'0');}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}
ll fact_pow(ll n,ll p){ll res=0;while(n){n/=p;res+=n;}return res;}
ll mult(ll a,ll b,ll p){a%=p;b%=p;ll r=0,v=a;while(b){if(b&1){r+=v;if(r>p)r-=p;}v<<=1;if(v>p)v-=p;b>>=1;}return r;}
ll quick_pow(ll a,ll b,ll p){ll r=1,v=a%p;while(b){if(b&1)r=mult(r,v,p);v=mult(v,v,p);b>>=1;}return r;}
bool CH(ll a,ll n,ll x,ll t)
{ll r=quick_pow(a,x,n);ll z=r;for(ll i=1;i<=t;i++){r=mult(r,r,n);if(r==1&&z!=1&&z!=n-1)return true;z=r;}return r!=1;}
bool Miller_Rabin(ll n)
{if(n<2)return false;if(n==2)return true;if(!(n&1))return false;ll x=n-1,t=0;while(!(x&1)){x>>=1;t++;}srand(time(NULL));
ll o=8;for(ll i=0;i<o;i++){ll a=rand()%(n-1)+1;if(CH(a,n,x,t))return false;}return true;}
int prime[30000010],minprime[30000010];
void euler(int n)
{int c=0,i,j;for(i=2;i<=n;i++){if(!minprime[i])prime[++c]=i,minprime[i]=i;for(j=1;j<=c&&i*prime[j]<=n;j++)
{minprime[i*prime[j]]=prime[j];if(i%prime[j]==0)break;}}}

const int N = 2e5 + 10;
char s[N] , t[N];
int main()
{
    ios;
    int q;
    cin >> q;
    while(q --)
    {
        int n ;
        cin >> n;
        cin >> s + 1 >> t + 1 ;
        int flag = 1 , cot = 1;
        rep(i , 1 , n)
        {
            if(!flag) break;
            if(s[i] == t[i])
            continue;
            else 
            {
                if(cot == 0)
                {
                    cout << "No\n";
                    flag = 0;
                    break;
                }
                int have = 0;
                rep(j , i + 1 , n)
                {
                    if(s[j] == s[i] && t[j] != s[j])
                    {
                        swap(t[i] , s[j]);
                        cot = 0;
                        have = 1;
                    }
                }
                if(!have)
                {
                    cout << "No\n";
                    flag = 0;
                }
            }
        }
        if(flag)
        cout <<"Yes\n";
    }
    return 0;
}
View Code

 

 

 

B2. Character Swap (Hard Version)

题目链接:https://codeforces.com/contest/1243/problem/B2

题意:

给你两个长度为 n 的字符串 S 和 T ,每次操作你可以交换 S 、T上任意两个位置的字符。

问在 2n 操作次数内能否是 S 等于 T,若可以则输出"Yes"并打印交换方法,若不可以则输出"No"

分析:

其实仔细观察我们会发现只要能够使S串变为T串,那么它的操作次数一定是在2n以内。

然而我们还是要优先选择优质的交换方法。

当 S[i] != T[i] 从后遍历判断是否存在S[j] == S[i] , 若存在则交换 T[i] 和 S[j] , 否则判断是否存在T[j] == S[i] ,若存在则可以先交换S[i] 和 T[i] ,再交换S[i] = T[j],若不存在则输出"No"

#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define pd(n) printf("%d\n", (n))
#define pdd(n,m) printf("%d %d\n", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n,m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define mm(a,n) memset(a, n, sizeof(a))
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define ll long long
#define MOD 1000000007
#define pi 3.14159265358979323
#define lrt rt<<1
#define rrt rt<<1|1
#define lson l, m, lrt
#define rson m+1, r, rrt
#define debug(x)               cout << #x << ": " << x << endl
#define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
#define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
#define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
using namespace std;
const ll INF (0x3f3f3f3f3f3f3f3fll);
const int inf (0x3f3f3f3f);
template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
for(res=ch-48;isdigit(ch=getchar());res=(res<<1)+(res<<3)+ch - 48);flag&&(res=-res);}
template<typename T>void Out(T x){if(x<0)putchar('-'),x=-x;if(x>9)Out(x/10);putchar(x%10+'0');}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}
ll fact_pow(ll n,ll p){ll res=0;while(n){n/=p;res+=n;}return res;}
ll mult(ll a,ll b,ll p){a%=p;b%=p;ll r=0,v=a;while(b){if(b&1){r+=v;if(r>p)r-=p;}v<<=1;if(v>p)v-=p;b>>=1;}return r;}
ll quick_pow(ll a,ll b,ll p){ll r=1,v=a%p;while(b){if(b&1)r=mult(r,v,p);v=mult(v,v,p);b>>=1;}return r;}
bool CH(ll a,ll n,ll x,ll t)
{ll r=quick_pow(a,x,n);ll z=r;for(ll i=1;i<=t;i++){r=mult(r,r,n);if(r==1&&z!=1&&z!=n-1)return true;z=r;}return r!=1;}
bool Miller_Rabin(ll n)
{if(n<2)return false;if(n==2)return true;if(!(n&1))return false;ll x=n-1,t=0;while(!(x&1)){x>>=1;t++;}srand(time(NULL));
ll o=8;for(ll i=0;i<o;i++){ll a=rand()%(n-1)+1;if(CH(a,n,x,t))return false;}return true;}
int prime[30000010],minprime[30000010];
void euler(int n)
{int c=0,i,j;for(i=2;i<=n;i++){if(!minprime[i])prime[++c]=i,minprime[i]=i;for(j=1;j<=c&&i*prime[j]<=n;j++)
{minprime[i*prime[j]]=prime[j];if(i%prime[j]==0)break;}}}
 
const int N = 2e5 + 10;
char s[N] , t[N]; 
pair<int , int>hehe;
vector<pair<int , int>>vec;
map<char ,int >haha;
int main()
{
    ios;
    int T;
    cin >> T;
    while(T -- )
    {
        haha.clear();
        vec.clear();
        int n;
        cin >> n;
        cin >> s + 1 >> t + 1 ;
    
        rep(i , 1 , n)
        haha[s[i]] ++ , haha[t[i]] ++ ;
        int flag = 0;
        rep(i , 0 , 25)
        {
            if(haha[i + 'a'] & 1)
            {
                flag = 1;
                break;
            }
        }
        if(flag)
        {
            cout << "No" << '\n';
            continue;
        }
        rep(i , 1 , n)
        {
            if(s[i] == t[i])
            continue;
            else 
            {
                int falg = 0;
                rep(j , i + 1 , n)
                {
                    if(s[i] == s[j])
                    {
                        hehe.first = j , hehe.second = i;
                        vec.pb(hehe);
                        swap(s[j] , t[i]);
                        falg = 1;
                        break;
                    }    
                }
                if(!falg)
                {
                    rep(j , i + 1 , n)
                    {
                        if(s[i] == t[j])
                        {
                            swap(s[i] , t[i]);
                            hehe.fi = i , hehe.se = i;
                            vec.pb(hehe);
                            swap(s[i] , t[j]);
                            hehe.fi = i , hehe.se = j;
                            vec.pb(hehe);
                            break;
                        }
                    }
                }
            }
        }
        int len = vec.size();
        if(len >= 2 * n)
        {
            cout << "No" << '\n';
            continue;
        }
        cout << "Yes" << '\n';
        cout << vec.size() << '\n';
        rep(i , 0 , vec.size() - 1)
        cout << vec[i].fi << " " << vec[i].se << '\n';
    } 
    return 0;
}
View Code

 

 

 

C. Tile Painting

题目链接:https://codeforces.com/contest/1243/problem/C

题意:

给你 n 个方格 , 第 i 个位置的倍数的颜色需要和 第 i 个位置的颜色相同,问你最多可以用多少种颜色来填充

分析:

找找规律我们会发现它是有循环节的,而循环节就是n / lcm = 所有因子的gcd

 #include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define pd(n) printf("%d\n", (n))
#define pdd(n,m) printf("%d %d\n", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n,m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define mm(a,n) memset(a, n, sizeof(a))
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define ll long long
#define MOD 1000000007
#define pi 3.14159265358979323
#define lrt rt<<1
#define rrt rt<<1|1
#define lson l, m, lrt
#define rson m+1, r, rrt
#define debug(x)               cout << #x << ": " << x << endl
#define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
#define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
#define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
using namespace std;
const ll INF (0x3f3f3f3f3f3f3f3fll);
const int inf (0x3f3f3f3f);
template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
for(res=ch-48;isdigit(ch=getchar());res=(res<<1)+(res<<3)+ch - 48);flag&&(res=-res);}
template<typename T>void Out(T x){if(x<0)putchar('-'),x=-x;if(x>9)Out(x/10);putchar(x%10+'0');}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}
ll fact_pow(ll n,ll p){ll res=0;while(n){n/=p;res+=n;}return res;}
ll mult(ll a,ll b,ll p){a%=p;b%=p;ll r=0,v=a;while(b){if(b&1){r+=v;if(r>p)r-=p;}v<<=1;if(v>p)v-=p;b>>=1;}return r;}
ll quick_pow(ll a,ll b,ll p){ll r=1,v=a%p;while(b){if(b&1)r=mult(r,v,p);v=mult(v,v,p);b>>=1;}return r;}
bool CH(ll a,ll n,ll x,ll t)
{ll r=quick_pow(a,x,n);ll z=r;for(ll i=1;i<=t;i++){r=mult(r,r,n);if(r==1&&z!=1&&z!=n-1)return true;z=r;}return r!=1;}
bool Miller_Rabin(ll n)
{if(n<2)return false;if(n==2)return true;if(!(n&1))return false;ll x=n-1,t=0;while(!(x&1)){x>>=1;t++;}srand(time(NULL));
ll o=8;for(ll i=0;i<o;i++){ll a=rand()%(n-1)+1;if(CH(a,n,x,t))return false;}return true;}
int prime[30000010],minprime[30000010];
void euler(int n)
{int c=0,i,j;for(i=2;i<=n;i++){if(!minprime[i])prime[++c]=i,minprime[i]=i;for(j=1;j<=c&&i*prime[j]<=n;j++)
{minprime[i*prime[j]]=prime[j];if(i%prime[j]==0)break;}}}
 
const int N = 2e5 + 10;
vector<ll>haha;
void init(ll n)
{
    ll i ;
    for(i = 2 ; i * i < n ; i ++)
    {
        if(n % i == 0)
        haha.pb(i) , haha.pb(n / i);
    }
    if(i * i == n)
    haha.pb(i);
}
int main()
{
    ios;
    haha.clear();
    ll n;
    cin >> n;
    init(n);
    haha.pb(n);
    ll ans = haha[0];
    rep(i , 0 , haha.size() - 1)
    ans = gcd(ans , haha[i]);
    cout << ans << '\n';
    return 0;
}
 
 
 
 
View Code

 

 

 

D. 0-1 MST

题目链接:https://codeforces.com/contest/1243/problem/D

题意:

给你一张包含 n 个点的完全图,其中有m条边的权值为1,其它的为0。现要求你求出最小生成树的权值

分析:

先将 n 个点存入 set<int> S(表示该点还未在任何连通块里),并用vis进行标记

再对每个点开个set<int>G用来存图

遍历每个点 , 若 vis[i] = 1 则将 i 从集合S中删除并以 i 为起点进行 bfs 寻找连通块 , 同时连通块个数 cnt ++。

bfs 过程中遍历S , 若 G[i].count(*it) == 1 , 则说明两点没有连通 , 若为 0 则说明两点有连通。若连通则将其从S中erase、vis标记为1,并加入队列进行下一轮bfs

最后输出 cnt - 1即可

 

#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define pd(n) printf("%d\n", (n))
#define pdd(n,m) printf("%d %d\n", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n,m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define mm(a,n) memset(a, n, sizeof(a))
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define ll long long
#define MOD 1000000007
#define pi 3.14159265358979323
#define lrt rt<<1
#define rrt rt<<1|1
#define lson l, m, lrt
#define rson m+1, r, rrt
#define debug(x)               cout << #x << ": " << x << endl
#define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
#define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
#define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
using namespace std;
const ll INF (0x3f3f3f3f3f3f3f3fll);
const int inf (0x3f3f3f3f);
template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
for(res=ch-48;isdigit(ch=getchar());res=(res<<1)+(res<<3)+ch - 48);flag&&(res=-res);}
template<typename T>void Out(T x){if(x<0)putchar('-'),x=-x;if(x>9)Out(x/10);putchar(x%10+'0');}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}
ll fact_pow(ll n,ll p){ll res=0;while(n){n/=p;res+=n;}return res;}
ll mult(ll a,ll b,ll p){a%=p;b%=p;ll r=0,v=a;while(b){if(b&1){r+=v;if(r>p)r-=p;}v<<=1;if(v>p)v-=p;b>>=1;}return r;}
ll quick_pow(ll a,ll b,ll p){ll r=1,v=a%p;while(b){if(b&1)r=mult(r,v,p);v=mult(v,v,p);b>>=1;}return r;}
bool CH(ll a,ll n,ll x,ll t)
{ll r=quick_pow(a,x,n);ll z=r;for(ll i=1;i<=t;i++){r=mult(r,r,n);if(r==1&&z!=1&&z!=n-1)return true;z=r;}return r!=1;}
bool Miller_Rabin(ll n)
{if(n<2)return false;if(n==2)return true;if(!(n&1))return false;ll x=n-1,t=0;while(!(x&1)){x>>=1;t++;}srand(time(NULL));
ll o=8;for(ll i=0;i<o;i++){ll a=rand()%(n-1)+1;if(CH(a,n,x,t))return false;}return true;}
int prime[30000010],minprime[30000010];
void euler(int n)
{int c=0,i,j;for(i=2;i<=n;i++){if(!minprime[i])prime[++c]=i,minprime[i]=i;for(j=1;j<=c&&i*prime[j]<=n;j++)
{minprime[i*prime[j]]=prime[j];if(i%prime[j]==0)break;}}}
 
const int N = 2e5 + 10;
set<int>G[N];
set<int>s;
set<int>::iterator it;
int n , m;
int vis[N]; 
void bfs(int x)
{
    queue<int>q;
    q.push(x);
    s.erase(x);
    vis[x] = 1;
    while(!q.empty())
    {
        int k = q.front();
        q.pop();
        for(it = s.begin() ; it != s.end() ;)
        {
            int ha = *it ++; 
            if(G[k].count(ha) == 0)
            {
                vis[ha] = 1;
                q.push(ha);
                s.erase(ha);
            }
        }
    }
}
int main()
{
    ios;
    cin >> n >> m;
    rep(i , 1 , n)
    s.insert(i);
    rep(i , 1 , m)
    {
        int x , y;
        cin >> x >> y;
        G[x].insert(y);
        G[y].insert(x);
    }
    int ans = 0;
    rep(i , 1 , n)
    {
        if(!vis[i])
        {
            ans ++;
            bfs(i);
        }
    }
    cout << ans - 1 << '\n';
    return 0;
}
 
View Code

 

posted @ 2019-11-11 19:24  GsjzTle  阅读(123)  评论(0编辑  收藏  举报