NOIP 模拟赛 3
NOIP 模拟赛总结
NOIP 模拟赛 3
CSP 出分了,没心情打模拟赛,呜呜呜~
T1 变形怪
简单签到题,直接爆搜即可。
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
#define Blue_Archive return 0
using namespace std;
constexpr int N = 2e3 + 3;
constexpr int M = 1e4 + 3;
constexpr char me[] = "終末なにしてますか?忙しいですか?救ってもらっていいですか?";
int n;
int m;
int ans;
int siz;
int x[13];
unordered_map<int,bool> mp;
queue<int> q;
inline int read()
{
int k = 0,f = 1;
char c = getchar_unlocked();
while(c < '0' || c > '9') c = getchar_unlocked();
while(c >= '0' && c <= '9') k = (k << 3) + (k << 1) + c - '0',c = getchar_unlocked();
return k * f;
}
inline void write(int x)
{
if(x < 0) putchar_unlocked('-'),x = -x;
if(x > 9) write(x / 10);
putchar_unlocked(x % 10 + '0');
}
inline int max(int x,int y){return x > y ? x : y;}
inline int min(int x,int y){return x < y ? x : y;}
signed main()
{
freopen("set.in","r",stdin);freopen("set.out","w",stdout);
// freopen("data.in","r",stdin);freopen("data.out","w",stdout);
n = read();
m = read();
for(int i = 1;i <= m;i ++) x[i] = read();
sort(x + 1,x + m + 1);
siz = unique(x + 1,x + m + 1) - x - 1;
q.push(n);
while(!q.empty())
{
int u = q.front();
q.pop();
if(mp[u]) continue;
mp[u] = 1;
ans ++;
for(int i = 1;i <= siz;i ++)
{
if(!mp[u / x[i]]) q.push(u / x[i]);
}
}
write(ans),ent;
Blue_Archive;
}
T2 忍者小队
神秘 DP。
非常简单可以把问题转化成求一个集合内最少有几个数使得其最大公因数为 \(1\)。
考虑到限制是从大到小依次增加的。
所以考虑从大到小枚举每个数,容斥一下。
考虑到值域只有 \(3 \times 10 ^ 5\)。
也就是最多有 \(7\) 个不同的质数相乘。
直接设 \(dp_{i,j}\) 表示有 \(j\) 个不同质数相乘的值为 \(i\) 的合法方案数。
然后转移方程为:\(dp_{j,i} = C(ans2[i],j) - dp_{j,i * k}\)。
当最后一个 \(dp_{i,j}\) 大于 \(0\) 时,答案即为 \(i\)。
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
#define Blue_Archive return 0
using namespace std;
constexpr int N = 6e5 + 3;
constexpr int mod = 1e9 + 7;
constexpr int INF = 1e18;
constexpr char me[] = "終末なにしてますか?忙しいですか?救ってもらっていいですか?";
int n;
int m;
int V;
int a[N];
int cnt[N];
int ans1[N];
int ans2[N];
int C[N][8];
int dp[8][N];
bitset<N> vis;
vector<int> op[N];
inline int read()
{
int k = 0,f = 1;
char c = getchar_unlocked();
while(c < '0' || c > '9') c = getchar_unlocked();
while(c >= '0' && c <= '9') k = (k << 3) + (k << 1) + c - '0',c = getchar_unlocked();
return k * f;
}
inline void write(int x)
{
if(x < 0) putchar_unlocked('-'),x = -x;
if(x > 9) write(x / 10);
putchar_unlocked(x % 10 + '0');
}
inline int max(int x,int y){return x > y ? x : y;}
inline int min(int x,int y){return x < y ? x : y;}
signed main()
{
freopen("sor.in","r",stdin);freopen("sor.out","w",stdout);
// freopen("data.in","r",stdin);freopen("data.out","w",stdout);
n = read();
m = read();
for(int i = 1;i <= n;i ++) // O(n \sqrt{n})
{
a[i] = read();
vis[a[i]] = 1;
cnt[a[i]] ++;
V = max(V,a[i]);
}
C[0][0] = 1;
for(int i = 1;i <= n;i ++)
{
C[i][0] = 1;
for(int j = 1;j <= 7;j ++)
{
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
}
}
for(int i = V,sum,gbc;i >= 1;i --)
{
sum = 0;
gbc = 0;
for(int k = 1;k * i <= V;k ++)
{
if(vis[i * k])
{
sum += cnt[i * k];
gbc = __gcd(gbc,k);
}
}
if(vis[i]){ans1[i] = 1;ans2[i] = sum;continue;}
if(gbc != 1){ans1[i] = ans2[i] = -1;continue;}
ans2[i] = sum;ans1[i] = INF;
}
for(int i = V;i >= 1;i --)
{
if(ans1[i] == -1) continue;
for(int j = 1;j <= 7;j ++)
{
dp[j][i] = C[ans2[i]][j];
for(int k = 2;k * i <= V;k ++) dp[j][i] = (dp[j][i] + mod - dp[j][i * k]) % mod;
if(dp[j][i] && ans1[i] == INF) ans1[i] = j;
}
}
for(int i = 1;i <= m;i ++) write(ans1[i]),con,write(ans2[i]),ent;
Blue_Archive;
}
T3:尘埃下的神话
不会,咕咕。
T4:怪盗德基
看不懂题面,咕咕。
与你的日常,便是奇迹

浙公网安备 33010602011771号