欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Codeforces Round #505 (rated, Div. 1 + Div. 2) B. Weakened Common Divisor

程序员文章站 2022-03-12 09:53:42
...

Codeforces Round #505 (rated, Div. 1 + Div. 2) B. Weakened Common Divisor

 

题意:定义弱因数x为满足对于一对数{a,b},{ x | !(x%a) || !(x%b) }

现在问你n对数的公共弱因数

 

这场比赛没打,但是吧赛时看了下题,和室友口胡了下正解是sqrt(a)+sqrt(b)时间计算出某对数的所有因数,设去重后一共有x个,之后for一遍所有对,总复杂度是Codeforces Round #505 (rated, Div. 1 + Div. 2) B. Weakened Common Divisor

 

然后早上一写,submit,TLE on test99

woc???t最后一组????

 

稍微再想一下我们可以发现,由于1e9内某些数的因子数量或超过1e3,例如{1889727840,1715313600},总个数x去重后大概有2e3多点

这样的话时间就是3e8多点,很容易被卡

 

那么怎么解决呢-----只遍历素因子就好了,素因子只有logn个,那么总复杂度就是Codeforces Round #505 (rated, Div. 1 + Div. 2) B. Weakened Common Divisor

对于所有因子,他们等效于他们的素因子,所以可以直接用素因子去遍历.

 

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int readn()
{
    int x=0;
    char ch=getchar();
    while(ch>'9'||ch<'0') ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
    return x;
}
vector<pair<int,int> > vp;
set<int> st;
int main()
{
    int n=readn();
    vp.clear(),st.clear();
    for(int i=0;i<n;i++)
    {
        int a=readn(),b=readn();
        vp.push_back(make_pair(a,b));
    }
    if(vp[0].first!=1) st.insert(vp[0].first);
    if(vp[0].second!=1) st.insert(vp[0].second);
    for(int i=2;i*i<=vp[0].first;i++)
    {
        if(vp[0].first%i==0)
        {
            st.insert(i);
            while(vp[0].first%i==0) vp[0].first/=i;
        }
    }
    for(int i=2;i*i<=vp[0].second;i++)
    {
        if(vp[0].second%i==0)
        {
            st.insert(i);
            while(vp[0].second%i==0) vp[0].second/=i;
        }
    }
    if(vp[0].first!=1) st.insert(vp[0].first);
    if(vp[0].second!=1) st.insert(vp[0].second);
    int flag=1;
    for(auto x:st)
    {
        flag=1;
        for(int i=1;i<n;i++)
        {
            if(vp[i].first%x==0||vp[i].second%x==0) continue;
            else
            {
                flag=0;
                break;
            }
        }
        if(flag) return printf("%d\n",x)*0;
    }
    printf("-1\n");
}

 

但是实际上,原来的做法是可以卡过去的,1466ms,cf神仙机orz

Codeforces Round #505 (rated, Div. 1 + Div. 2) B. Weakened Common Divisor

 

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
int a[maxn];
int b[maxn];
vector<int> v;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d%d",&a[i],&b[i]);
    for(int i=1;i*i<=a[0];i++)
    {
        if(a[0]%i==0)
        {
            if(i!=1) v.push_back(i);
            if(a[0]!=i) v.push_back(a[0]/i);
        }
    }
    for(int i=1;i*i<=b[0];i++)
    {
        if(b[0]%i==0)
        {
            if(i!=1) v.push_back(i);
            if(b[0]!=i) v.push_back(b[0]/i);
        }
    }
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    for(auto x:v)
    {
        int flag=1;
        for(int i=1;i<n;i++)
        {
            if(a[i]%x&&b[i]%x)
            {
                flag=0;
                break;
            }
        }
        if(flag) return printf("%d\n",x)*0;
    }
    return printf("-1\n")*0;
}

 

相关标签: math