Codeforces Round #109 (Div. 2) D. Colliders 数学

来源:互联网 发布:通天西游坐骑进阶数据 编辑:程序博客网 时间:2024/06/01 07:47

一直觉得codeforces上的题解法都很新奇,这个也不例外,说说题意,

最大10^5的数,进行10^5次操作,每一次进行加入或者删除一个数,加入时:只有与已加入的数互素才能加入,不能加入的,输出原因(与某个不互素,或者,已经加入)。删除时:输出删除成功,或者尚未加入。

这个题看起来不简单,经过分析之后,我发现,对于10^5这么大的数,只能最多有7个不同的素数的幂的积的形式,要使互素,也就是说,没有共同的素数因子,按照这个思路,我们对每一个数的素数因子进行标记,插入的时候,就可以查询插入的这个数的素数因子有没有出现

这个思路的时间复杂度是O(10^5*7),这个复杂度是可以解决的。

但是,其中有一个需要输出与第几个互素,这个也需要标记。ok,代码见下面

#include <iostream>#include <stdio.h>#include <string.h>using namespace std;#define N 1000010int prime[N];bool isPrime[N+1];int size;void getPrime() {    size = 0;    memset(isPrime,true,sizeof(isPrime));    int i;    for(i=2; i<=N/2; i++) {        if(isPrime[i])  //i是素数            for(int j=i+i; j<=N; j+=i)                isPrime[j]=0;    }    for(i=2; i<=N; i++) {        if(isPrime[i])            prime[size++]=i;    }}bool active[100010];int data[100010][10];int count[100010];//计数出现这个素数的jint main(){    //cout << 2*3*5*7*11*13*17;    getPrime();    for(int i = 0;i < size;i++)    {        for(int j = prime[i];j < 100010;j += prime[i])            data[j][ ++data[j][0] ] = prime[i];    }    int n,m;    scanf("%d%d",&n,&m);    memset(active,0,sizeof(active));    memset(count,0,sizeof(count));    char c[2];int t;    for(int i = 0;i < m;i++)    {        scanf("%s%d",c,&t);        if(c[0] == '+')        {            //1 success 2 already on 3冲突            if(active[t])                printf("Already on\n");            else            {                bool b = 0;                for(int j = 1;j <= data[t][0];j++)                    if(count[ data[t][j] ])                    {                        printf("Conflict with %d\n",count[ data[t][j] ]);                        b = 1;break;                    }                if(!b)                {                    for(int j = 1;j <= data[t][0];j++)                        count[ data[t][j] ] = t;                    printf("Success\n");                    active[t] = 1;                }            }        }else //--        {            if(!active[t])                printf("Already off\n");            else            {                for(int j = 1;j <= data[t][0];j++)                    count[ data[t][j] ] = 0;                printf("Success\n");                active[t] = 0;            }        }    }    return 0;}



原创粉丝点击