当前位置: 首页 > news >正文

CSP-S模拟27

CSP-S模拟27

今天早上还在被窝里愉悦地睡懒觉,下午就在学校里打上模拟赛了。。。

一上午都处在又困又饿的状态,到了下午稍微好了一点。

T1:喜剧的迷人之处在于

一个挺显然的题,很容易去想到将 \(a\) 去质因数分解,然后直接枚举未配对的因数的倍数即可。

要预处理一个平方数数组,直接二分,时间复杂度是 \(T \sqrt a \log1000000\)

点击查看代码

#include<bits/stdc++.h>
#define int long long 
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;
constexpr int N = 1e6 + 7;
constexpr int INF = 1e18;int T;
int a;
int l;
int r;
int tot;
int ans;
int op[N];
int pri[N];bool st[N];inline int read()
{int x = 0;char c = getchar_unlocked();for(;!isdigit(c);c = getchar_unlocked());for(;isdigit(c);x = x * 10 + c - 48,c = getchar_unlocked());return x;
}inline void write(int x)
{if(x < 0) putchar_unlocked('-'),x = -x;if(x > 9) write(x / 10);putchar_unlocked(x % 10 + '0');
}inline void init()
{for(int i = 2;i <= 1000000;i ++){if(!st[i]) pri[++ tot] = i;for(int j = 1;j <= tot && pri[j] * i <= 1000000;j ++){st[i * pri[j]] = 1;if(i % pri[j] == 0) break;}}for(int i = 1;i <= 1000000;i ++) op[i] = i * i;
}signed main()
{// freopen("data.in","r",stdin);freopen("data.out","w",stdout);init();T = read();while(T --){ans = 1;a = read();l = read();r = read();for(int i = 1,cnt;i <= tot && a > 1;i ++) // sqrt(a) ? {if(a % pri[i] == 0){cnt = 0;while(a % pri[i] == 0) a /= pri[i],cnt ++; cnt %= 2;if(cnt) ans = ans * pri[i];}}int pos = lower_bound(op + 1,op + 1000000 + 1,l / ans) - op; // 大于等于它的if(op[pos] * ans >= l && op[pos] * ans <= r) write(op[pos] * ans),ent;else if(op[pos + 1] * ans >= l && op[pos + 1] * ans <= r) write(op[pos + 1] * ans),ent;else write(-1),ent;}Blue_Archive;
}

T2:镜中的野兽

写了一辈子的T2,花半小时写T1,花半小时写T3、T4的暴力,花三小时写T2。。。

是一个比较困难的题(至少对我来说)

首先非常显然的是:一个序列的 \(gcd\) 肯定是 \(lcm\) 的因子。

于是我们就可以枚举倍数(因为题面中给的是 \(gcd\)\(lcm\) 的和)\(k\)

显然可得 \(gcd\) = \(k\)\(lcm\) = \(m - k\)

我们发现这与 \(gcd\) == \(1\)\(lcm\) = \((m - k) / k\) 是等价的,并且下者更好维护(因为有互质)

然后我就不会做了。。。

这就是赛时思路。之后一直尝试找规律,找到了 \(n == 2\)\(n == 3\) 的规律,然后只拿了 25 pts。

考虑如何去计数。

我们发现只有两个限制条件:一个是存在互质,一个是要满足我们找到的 \((m - k) / k\) 是这个序列的 \(lcm\)

而且发现如果没有这两个条件的话,答案非常好求:直接上组合数就好。

考虑将 \((m - k) / k\) 唯一分解,各个质因子的系数的和中选 \(n\) 个数即为没有限制条件的答案。

然后考虑分别满足这两个条件。

只需要枚举 \(lcm\) 每个质因子,然后直接上容斥即可(啊啊啊,为什么赛时没想出来容斥啊)。

tips:本题也可以直接上莫反去做,因为反演式子还挺板的。(前提是你得会莫比乌斯反演)

点击查看代码
#include<bits/stdc++.h>
#define int long long 
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;constexpr int N = 1e5 + 10;int n;
int m;
int mod;
int ans;
int cnt;
int top;
int stk[N];
int tim[N];
int pri[N];
int fac[N];
int inv[N];bool st[N];inline int read()
{int k = 0,f = 1;char c = getchar_unlocked();while(c < '0' || c > '9'){if(c == '-') f = -1;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 qpow(int a,int b)
{int res = 1;while(b){if(b & 1) res = (res * a) % mod;a = (a * a) % mod;b >>= 1;}return res;
}inline void init(int n)
{fac[0] = inv[0] = 1;for(int i = 1;i <= n;i ++){fac[i] = fac[i - 1] * i % mod;inv[i] = qpow(fac[i],mod - 2);} for(int i = 2;i <= n;i ++){if(!st[i]) pri[++ cnt] = i;for(int j = 1;pri[j] * i <= n && j <= cnt;j ++){st[i * pri[j]] = 1;if(i % pri[j] == 0) break;}}
}inline int C(int n,int m)
{if(n < m) return 0;return fac[n] * inv[m] % mod * inv[n - m] % mod;
}inline int F(int x)
{if(x == m) return 0;int op = (m - x) / x;top = 0;for(int i = 1;i <= cnt && pri[i] * pri[i] <= op;i ++){if(op % pri[i]) continue;stk[++ top] = pri[i];tim[top] = 0;while(op % pri[i] == 0) tim[top] ++,op /= pri[i];}if(op > 1){stk[++ top] = op;tim[top] = 1;}int U = (1 << (top * 2)) - 1;int res = 0;for(int S = 0,x;S <= U;S ++) // 枚举每个集合{x = 1;for(int i = 1,u,v;i <= top;i ++) // 看看是不是能达到上界{u = (S >> (i - 1)) & 1;v = (S >> (i + top - 1)) & 1;if(u + v > tim[i] + 1){x = 0;break;}else x *= tim[i] + 1 - u - v;}if(__builtin_popcount(S) & 1) res = (res - C(x,n) + mod) % mod;else res = (res + C(x,n)) % mod;if(!S && x < n) return 0;}return res;
}signed main()
{// freopen("data.in","r",stdin);freopen("data.out","w",stdout);n = read();m = read();mod = read();init(N - 10);for(int i = 1;i * i <= m;i ++){if(m % i != 0) continue;ans = (ans + F(i)) % mod;if(i * i != m) ans = (ans + F(m / i)) % mod;}write(ans);ent;Blue_Archive;
}

T3:我愿相信由你所描述的童话

严格简单于 T2。

考虑两个 \(dp\)。分别是从左往右的贡献和从右往左的贡献。

然后枚举汇合点即可。

直接做的话,时间复杂度是 \(O(n2^m)\)

不可过(其实可过)。

考虑优化,like 折半搜索,每次查询时枚举前 \(m / 2\) 位的子集查询,修改时枚举后 \(m / 2\) 位的超集修改。

这样可以做到 \(O(n2^{m / 2})\)

但是我直接找了一篇能过的 \(O(n2^m)\)

所以代码是 \(O(n2^m)\) 的。

嘻嘻

点击查看代码

#include<bits/stdc++.h>
#define int long long 
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;
constexpr int N = 3e5 + 7;
constexpr int M = (1 << 20) + 7;
constexpr int mod = 1e9 + 7;
constexpr int INF = 1e18;int n;
int m;
int ans;
int a[N];
int f[M];
int as[N];
int dp[M];inline int read()
{int x = 0;char c = getchar_unlocked();for(;!isdigit(c);c = getchar_unlocked());for(;isdigit(c);x = x * 10 + c - 48,c = getchar_unlocked());return x;
}inline void write(int x)
{if(x < 0) putchar_unlocked('-'),x = -x;if(x > 9) write(x / 10);putchar_unlocked(x % 10 + '0');
}signed main()
{// freopen("data.in","r",stdin);freopen("data.out","w",stdout);n = read();m = read();for(int i = 1;i <= n;i ++) a[i] = read();for(int i = 1,j,now,op;i <= n;i ++){j = 0,now = a[i];op = max(now & (-now),1ll);as[i] = 1;while(j < now){if((now | j) == now) (as[i] += f[j]) %= mod,j += op;else j += j & (-j);}f[now] = ((f[now] << 1) + as[i]) % mod;}for(int i = n,j,now,op,sum;i >= 1;i --){j = 0;sum = 1;now = a[i];op = max(now & (-now),1ll);while(j <= now){if((now | j) == now) (sum += dp[j]) %= mod,j += op;else j += j & (-j);}(dp[now] += sum) %= mod;(ans += as[i] * sum % mod) %= mod;}write(ans);ent;Blue_Archive;
}

T4:Baby Doll

看不懂,结论题,贺题解贺出来 10 pts,然后就不会了。

点击查看代码
#include<bits/stdc++.h>
#define int long long 
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;
constexpr int N = 5e7 + 7;
constexpr int INF = 1e18;int n;
int m;
int q;
int mod;
int ans;
int a[N];
int fac[N];inline int read()
{int x = 0;char c = getchar_unlocked();for(;!isdigit(c);c = getchar_unlocked());for(;isdigit(c);x = x * 10 + c - 48,c = getchar_unlocked());return x;
}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 qpow(int a,int b)
{int res = 1;while(b){if(b & 1) res = (res * a) % mod;a = (a * a) % mod;b >>= 1;}return res;
}signed main()
{// freopen("data.in","r",stdin);freopen("data.out","w",stdout);n = read();m = read();mod = read();q = read();a[0] = fac[0] = 1;for(int i = 1;i <= n + m;i ++) a[i] = ((1 - qpow(q,i)) * qpow(1 - q,mod - 2) % mod + mod) % mod;for(int i = 1;i <= n + m;i ++) fac[i] = fac[i - 1] * a[i] % mod;ans = fac[n + m] * qpow(fac[n],mod - 2) % mod * qpow(fac[m],mod - 2) % mod;write(ans);ent;Blue_Archive;
}
http://www.sczhlp.com/news/181128/

相关文章:

  • 【GitHub每日速递 251010】Zen MCP:一键 orchestrate 多 AI 模型,代码开发协作新革命!
  • 做网站营销公司排名贵阳建站推广公司
  • 没有做icp备案的网站wordpress研究
  • 哪些公司做网站好wordpress误删插件
  • 乐至县建设局网站免费搜索引擎推广方法有哪些
  • 美橙互联 网站备案app开发平台搭建
  • 自助建站系统是怎么实现高邮建设银行网站
  • 西安做百度推广网站 怎样备案仿淘宝商城网站开源系统
  • 响应式网站模板xdwordpress前端发布插件
  • 大理北京网站建设18款安全应用软件免费大全
  • asp网站管理系统源码网络教育平台
  • 建设企业网站开发公司做网站服务器怎么用
  • 成都网站建设树莓网站开发外包维护合同
  • 昆明企业网站开发adspower指纹浏览器
  • 怎么在国外网站赚钱怎么进行网站建设
  • 端州网站建设公司WordPress怎么批量上传图片
  • 网站的概念硬件开发板
  • 成都网站建设制作公司网站定制制作
  • 有没有什么好的网站做淘宝客网站需要什么资质
  • 网站开发运行环境论文python云服务器网站开发实例
  • 网站开发学的啥网站服务器 免费
  • 深圳网站建设公司联华帮人做彩票网站
  • 做资讯类网站h5案例网站
  • 制作网站的第一步零售网站开发
  • 网站开发的在线支付功能留言网站建设
  • 中国移动官方网站如何制作投票小程序
  • 近期网络营销的热点事件乐云seo网站建设公司
  • 网站推广外贸怎么入驻京东商家平台
  • 网站源码下载 用户注册做门户网站需要什么
  • 个人网站系统中国四大软件外包公司是哪四个