• URAL1765 Error 404


    题目描述:

    vjudge

    题解:

    STO ljx OTZ

    下面这个算法是这位贡献的。


    不妨将删去改为加入。

    那么对于$n=p^k$,即只有一个质因子的$n$来说,若$i$已选,那么$i+n/p$、$i+2*n/p$……都必选。

    这个先感性理解一下。

    根据这个可以$O(n)$出解。

    再看$n=p1^{k1}*p2^{k2}$,即有两个质因子。

    对于已选点$i$有两种选择,一种是$i+n/p1$、$i+2*n/p1$……都选,另一种是$i+n/p2$、$i+2*n/p2$……都选。

    这个可以将原来的$n$个点分成$n/p1/p2$组,每组都两种选择,即要么分$p1$小组,要么分$p2$小组。

    时间复杂度貌似也是$O(n)$??!

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 20050;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int n,k,m[10],c;
    bool vis[N],vis1[N],vis2[N];
    void init()
    {
        int n0 = n;
        for(int i=2;i*i<=n0;i++)if(n0%i==0)
        {
            m[++c] = i;
            while(n0%i==0)n0/=i;
        }
        if(n0!=1)m[++c]=n0;
    }
    int cxk(int x){return x<n?x:x%n;}
    int sta[N],tl;
    int main()
    {
        read(n),read(k);init();
        if(c==1)
        {
            int ans = 0;
            for(int x,i=1;i<=k;i++)
            {
                read(x);x--;vis[x]=1;
                if(!vis1[x])
                {
                    vis1[x] = 1;ans += m[1];
                    int j = cxk(x+n/m[1]);
                    while(j!=x)vis1[j]=1,j=cxk(j+n/m[1]);
                }
            }
            if(ans==n)puts("-1");
            else
            {
                printf("%d
    ",ans-k);
                for(int i=0;i<n;i++)if(!vis[i]&&vis1[i])
                    printf("%d ",i+1);
                puts("");
            }
            return 0;
        }else
        {
            for(int x,i=1;i<=k;i++)
            {
                read(x),x--,vis[x]=1;
                if(!vis1[x])
                {
                    for(int j=x,k=1;k<=m[1];j=cxk(j+n/m[1]),k++)vis1[j]=1;
                }
                if(!vis2[x])
                {
                    for(int j=x,k=1;k<=m[2];j=cxk(j+n/m[2]),k++)vis2[j]=1;
                }
            }
            for(int i=0;i<n/m[1]/m[2];i++)
            {
                int c1 = 0,c2 = 0;
                for(int j=i,k=1;k<=m[1]*m[2];j=cxk(j+n/m[1]/m[2]),k++)
                {
                    if(!vis[j]&&vis1[j])c1++;
                    if(!vis[j]&&vis2[j])c2++;
                }
                if(c1<c2)
                {
                    for(int j=i,k=1;k<=m[1]*m[2];j=cxk(j+n/m[1]/m[2]),k++)
                        if(!vis[j]&&vis1[j])sta[++tl]=j+1;
                }else
                {
                    for(int j=i,k=1;k<=m[1]*m[2];j=cxk(j+n/m[1]/m[2]),k++)
                        if(!vis[j]&&vis2[j])sta[++tl]=j+1;
                }
            }
            if(tl+k==n)puts("-1");
            else
            {
                sort(sta+1,sta+1+tl);
                printf("%d
    ",tl);
                for(int i=1;i<=tl;i++)
                    printf("%d ",sta[i]);
                puts("");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    获取移动端屏幕的宽度的方法
    document.body 与 document.documentElement区别介绍
    鼠标放上去会变化
    获取当前日期的函数
    侧边栏和右边高度的问题
    【Ajax】接收后台数据在html页面显示
    JS获取屏幕的大小
    python——字符串的方法及注释&字符串格式化符号含义及转义字符含义
    python——元组
    python——列表操作符
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10872286.html
Copyright © 2020-2023  润新知