CSP模拟8

.....给自己考傻了,有点开摆的感觉。

A. Coprime 2

题目链接

比较的简单,和洛谷的月赛题差不多。

先把质数都筛出来,然后标记 n 个数的质因子。(预处理)

然后把询问的数枚举,查质因子,然后就没了。

复杂度 O(nlog2n).

复制代码
T1
#include <iostream>
#include <cstdio>

#define rint register int 

const int MAXN=2e6+5; 

using namespace std;

inline int read() {
    int f=1,x=0;
    char ch=getchar();
    while(ch<'0' || ch>'9') {
        if(ch=='-') {
            f=-1;
        }
        ch=getchar();
    }
    while(ch>='0' && ch<='9') {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
} 

int n,m,tot; 
int a[MAXN],ans[MAXN],zs[MAXN]; 

int main() {
    
    n=read() , m=read();
    for(rint i=1;i<=n;i++) {
        int x;
        x=read();
        
        int now=x;
        for(rint j=2;j*j<=x;j++) {
            if(now%j==0) {
                zs[j]=1;
                while(now%j==0) {
                    now/=j;
                    if(zs[now]) break;
                }
            }
            if(zs[now]) break; 
        }
        if(now!=1) {
            zs[now]=1;
        }
    }
    
    ans[++tot]=1;
    
    for(rint i=2;i<=m;i++) {
        
        bool flag=1;
        int now=i;
        for(int j=2;j*j<=i;j++) {
            if(now%j==0) {
                if(zs[j]) {
                    flag=0;
                    break;
                }
                while(now%j==0) {
                    now/=j;
                }
            }
        }
        if(now!=1 && zs[now]) {
            flag=0;
        }
        
        if(flag==1) {
            ans[++tot]=i;
        }
    }
    
    printf("%d\n",tot);
    
    for(rint i=1;i<=tot;i++) {
        printf("%d\n",ans[i]);
    }
    
    return 0;
} 

复制代码

 

B. Dist Max 2

题目链接

一眼二分,然后考场上不知怎么的,竟然认为二分不行,然后就寄了。

正解确实是二分。

遇事不决先排序先把其按x为关键字从小到大排序,然后就是二分答案。

设当前check的长度为 len,在来两个指针 lr ,保证两指针x的差值>=len,再在指针的两头判断,相当于把数列分为三部分,在左右两部分找答案。

复杂度 O(nlog2n);

复制代码
#include <iostream>
#include <cstdio>

#define rint register int 

const int MAXN=2e6+5; 

using namespace std;

inline int read() {
    int f=1,x=0;
    char ch=getchar();
    while(ch<'0' || ch>'9') {
        if(ch=='-') {
            f=-1;
        }
        ch=getchar();
    }
    while(ch>='0' && ch<='9') {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
} 

int n,m,tot; 
int a[MAXN],ans[MAXN],zs[MAXN]; 

int main() {
    
    n=read() , m=read();
    for(rint i=1;i<=n;i++) {
        int x;
        x=read();
        
        int now=x;
        for(rint j=2;j*j<=x;j++) {
            if(now%j==0) {
                zs[j]=1;
                while(now%j==0) {
                    now/=j;
                    if(zs[now]) break;
                }
            }
            if(zs[now]) break; 
        }
        if(now!=1) {
            zs[now]=1;
        }
    }
    
    ans[++tot]=1;
    
    for(rint i=2;i<=m;i++) {
        
        bool flag=1;
        int now=i;
        for(int j=2;j*j<=i;j++) {
            if(now%j==0) {
                if(zs[j]) {
                    flag=0;
                    break;
                }
                while(now%j==0) {
                    now/=j;
                }
            }
        }
        if(now!=1 && zs[now]) {
            flag=0;
        }
        
        if(flag==1) {
            ans[++tot]=i;
        }
    }
    
    printf("%d\n",tot);
    
    for(rint i=1;i<=tot;i++) {
        printf("%d\n",ans[i]);
    }
    
    return 0;
} 
View Co
复制代码

 

C. Count Multiset

题目链接

考试时写了一个四维的dp方程,给我自己惊呆了。不过没写就是了。

和CSP模拟7的T3挺像的,首先不考虑m的限制,

fi,j 表示分成了 i 个数,总和为 j ,列出一个状态转移方程(也就是构造一个升序序列):

fi,j=fi-1,j-1+fi,j-i;

对于 fi-1,j-1,相当于在数列前填一个1

对于 fi,j-i,相当于把所有数抬高1

然后再考虑 m 的限制,也就是1不能随便加了,那就容斥掉 1的个数超过m的方案数

即:

fi,j=fi-1,j-1+fi,j-i-fi-(m+1),j-i

然后就无了;

复杂度 O(n2);

复制代码
#include <iostream>
#include <cstdio>
 
const int MAXN=5010;
const int mod=998244353; 
 
using namespace std;

int set; 

inline int read() {
    int f=1,x=0;
    char ch=getchar();
    while(ch>'9' or ch<'0') {
        if(ch=='-') {
            f=-1;
        }
        ch=getchar();
    }
    while(ch>='0' and ch<='9') {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    return f*x;
}

int n,m,ans;
int dp[MAXN][MAXN];

int main() {
    
    n=read() , m=read();
    
    dp[0][0]=1;
    
    for(int i=1;i<=n;i++) {
        if(i<=m) {
            dp[i][i]=1;
        }
        else {
            break;
        }
    }
    
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=m;j++) {
            dp[i][j]=dp[i-1][j-1]; 
            if(j>=i) {
                dp[i][j]+=dp[i][j-i];
            }
            if(i>=m+1 and j>=i) {
                dp[i][j]-=dp[i-m-1][j-i];
                dp[i][j]%=mod;
            }
            dp[i][j]%=mod;
        }
    }
    
    for(int i=1;i<=n;i++) {
        printf("%d\n",dp[i][n]%mod);
    }
    
    
    return 0;#include <iostream>
#include <cstdio>
 
const int MAXN=5010;
const int mod=998244353; 
 
using namespace std;

int set; 

inline int read() {
    int f=1,x=0;
    char ch=getchar();
    while(ch>'9' or ch<'0') {
        if(ch=='-') {
            f=-1;
        }
        ch=getchar();
    }
    while(ch>='0' and ch<='9') {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    return f*x;
}

int n,m,ans;
int dp[MAXN][MAXN];

int main() {
    
    n=read() , m=read();

    dp[0][0]=1;
    
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            dp[i][j]+=dp[i-1][j-1]; 
            if(j>=i) {
                dp[i][j]+=dp[i][j-i];
            }
            if(i>=m+1 and j>=i) {
                dp[i][j]-=dp[i-m-1][j-i];
                dp[i][j]%=mod;
            }
            dp[i][j]%=mod;
        }
    }
    
    for(int i=1;i<=n;i++) {
        printf("%d\n",dp[i][n]%mod);
    }
    
    
    return 0;
} 
View Code
复制代码

至于T4,摆了摆了,有时间再写。

posted @   Trmp  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
-->
点击右上角即可分享
微信分享提示