CSP-S 模拟测试57题解
人生第一次A,B层一块考rank2,虽然说分差没几分,但还是值得纪念。
题解:
T1 天空龙:
大神题,因为我从不写快读也没有写考场注释的习惯,所以不会做,全hzoi就kx会做,kx真大神级人物。
T2 巨神兵:
大神题,一看数据范围这么小,我们考虑状压,最傻逼的暴力思路是压边,但是这显然不行。正解是压点,设$f[s]$为当前选定点集状态为$s$的方案数。
我们考虑转移,当前选定的点集肯定是可以通过边和没有连过来的点相连构成新的方案。所以转移所以我们考虑枚举补集的子集$k$,设$cnt$为s与k两个点集相连的边数,那么转移为$f[s|k]+=f[s]*2^{cnt}$?不,这样会算重,因为比如我们先加A点,再加B点,和先加B点,再加A点是一样的。所以考虑容斥,容斥系数为$(-1)^{size[k]+1}$,蒟蒻博主不会正着推,但是这个可以证明是对的。我们设$g[i]$为转移了$i$层的系数,那么显然$g[0]=1$,然后$g$的递推式为$g[i]=\sum_{j=1}^{i}{C_{j}^{i}*(-1)^{j+1}*g[i-j]}$,我们要证的是$g[i]=1$,首先$g[i-j]$可以消掉,因为你由3层转移到5层,和从0层转移到2层是一样的然后
$\sum_{j=1}^{i}{C_j^i*(-1)^{j+1}}$
$=(-1)*(\sum_{j=0}^{i}{C_j^i*(-1)^{j}}-C_j^0*(-1)^0)$
$=(-1)*((1-1)^i-1)=1$ 证毕。
然后转移用了很多预处理,主要是找两个点集相连的边,我们首先预处理每个点与之相连点的状态,将它与上当前枚举的补集就好,然后还要预处理的是,每个二进制数中1的个数和每个取出来的1,是第几位,然后dp就好了。
- #include<bits/stdc++.h>
- using namespace std;
- #define int long long
- const int N=,mod=1e9+;
- int first[N],nex[N],to[N],tot,rc[N],sta[N],ma[],f[],n,m,qpow[N],re[N];
- void add(int a,int b){
- to[++tot]=b,nex[tot]=first[a],first[a]=tot;
- }
- signed main(){
- scanf("%lld%lld",&n,&m);
- for(int i=;i<=m;++i){
- int x,y;
- scanf("%lld%lld",&x,&y);
- add(x,y);
- }
- for(int i=;i<=(<<n);++i){
- ma[i]=ma[i>>]+(i&);
- }
- // for(int i=1;i<=1<<n;++i) cout<<"ma["<<i<<"]=="<<ma[i]<<" ";cout<<endl;
- f[]=qpow[]=;
- for(int i=;i<=n*n;++i) qpow[i]=(qpow[i-]<<)%mod;
- for(int i=;i<=n+;++i) rc[i]=(i&)?-:;
- // for(int i=0;i<=n+1;++i) cout<<rc[i]<<" ";cout<<endl;
- for(int i=;i<=n;++i){
- re[<<i-]=i;
- for(int j=first[i];j;j=nex[j]){
- sta[i]|=<<to[j]-;
- }
- }
- int Max=<<n,cnt=,maxn=Max-;
- for(register int s=;s^Max;++s){register int kl=~s;
- for(register int i=kl&maxn;i;i=(i-)&kl){
- cnt=;
- for(register int j=s;j;j-=j&-j) cnt+=ma[sta[re[j&-j]]&i];
- // cout<<cnt<<" ";
- // cout<<f[s]%mod*qpow[cnt]%mod<<" ";
- (f[s|i]+=rc[ma[i]+]*f[s]%mod*qpow[cnt]%mod)%=mod;
- }
- }
- printf("%lld\n",(f[maxn]+mod)%mod);
- }
obelisk
T3 太阳神:
正难则反,lcm大于n的不好求,我们可以考虑求小于n的,即$n^2-\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}{[lcm(i,j)<=n]}$
然后再转化$n^2-\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}{[\frac{i\times j}{gcd(i,j)}<=n]}$,难点在于求后面的那部分,现在我们考虑枚举,$i,j$的最大公约数d,柿子就变成了$\sum\limits_{d=1}^{n}\sum\limits_{a=1}^{\frac{n}{d}}\sum\limits_{b=1}^{\frac{n}{d}}{[gcd(a,b)==1][a\times b\leq \frac{n}{d}]}$
我们考虑求$f_k=\sum\limits_{1\leq a,b\leq n}{[a\times b\leq k][gcd(a,b)==1]}$,我们设$S_k=\sum\limits_{1\leq a,b\leq n}{[a\times b\leq k]}$,这一个数论分块就可以求出,那么$f_k=S_k-\sum\limits_{t>1} f_{\frac{k}{t^2}}$,前面S函数是不考虑gcd为1的条件的,后面的t相当于是枚举a,b的因子,同时把a,b因子提出即可得到$\frac{k}{t^2}$,然后就是关于f函数的求法,把它差分一下得到g[k],那么g[k]的含义就是$\sum\limits [a\times b=k][gcd(a,b)=1]$的a,b对数
$g[k]=2^cnt$,cnt为k的质因子种数,因为每种质因子,只能全部给a或b,而不能一部分给a,一部分给b,因为那样的话$gcd(a,b)$就不是1,这样f线筛即可,当n较小时直接用线筛筛出来的,当n较大时用上面提到的方法迭代即可。最外层数论分块,时间复杂度O(玄学)$O(n^{\frac{2}{3}})$
- #include<bits/stdc++.h>
- using namespace std;
- #define int long long
- const int N=1e7+,mod=1e9+;
- int v[N],prime[N],num,f[N],n;
- void init(){
- f[]=;
- for(int i=;i<=;++i){
- if(!v[i]){
- prime[++num]=i;
- f[i]=;
- v[i]=;
- }
- for(int j=;j<=num&&i*prime[j]<=;++j){
- v[i*prime[j]]=;
- if(i%prime[j]==){
- f[i*prime[j]]=f[i];
- break;
- }
- f[i*prime[j]]=f[i]*f[prime[j]]%mod;
- // cout<<f[i]<<" "<<f[prime[j]]<<" "<<f[i*prime[j]]<<endl;
- }
- }
- }
- int calS(int x){
- int ans=;
- for(int l=,r;l<=x;l=r+){
- r=x/(x/l);
- (ans+=(r-l+)*(x/l)%mod)%=mod;
- }
- return ans;
- }
- int calF(int x){//cout<<x<<" "<<endl;
- if(x<=) return f[x];
- int ans=;
- ans=calS(x)%mod;
- for(int i=;i*i<=x;++i){
- (((ans-=calF(x/(i*i))+mod)%=mod)+=mod)%=mod;
- }
- return ans;
- }
- signed main(){
- scanf("%lld",&n);
- init();
- //for(int i=1;i<=20;++i) cout<<"f["<<i<<"]=="<<f[i]<<" ";cout<<endl;
- for(int i=;i<=;++i) (f[i]+=f[i-])%=mod;
- int ans=(n%mod*(n%mod))%mod;
- for(int i=,r;i<=n;i=r+){
- r=n/(n/i);
- // cout<<ans<<" ";
- // cout<<i<<" "<<r<<endl;
- (((ans-=calF(n/i)%mod*(r-i+)%mod+mod)%=mod)+=mod)%=mod;
- // cout<<calF(n/i)%mod*(r-i+1)%mod+mod<<endl;
- }
- printf("%lld",(ans+mod)%mod);
- }
ra
CSP-S 模拟测试57题解的更多相关文章
- [考试反思]1002csp-s模拟测试57:平庸
一天两场,感觉要完. 不粘排行榜,太壮观了. #1:190 #2:180 #4:160 #35:150 #37:140 #39:120 #kx:20呃... 最后一个是考试结束后了. 又是CE盖40分 ...
- CSP-S 模拟测试94题解
T1 yuuustu: 可以对两边取对数,然后就转化为两个double的比较,时间复杂度$O(n)$ 然后我就用神奇0.4骗分水过 #include<bits/stdc++.h> usin ...
- CSP-S模拟测试 88 题解
T1 queue: 考场写出dp柿子后觉得很斜率优化,然后因为理解错了题觉得斜率优化完全不可做,只打了暴力. 实际上他是可以乱序的,所以直接sort,正确性比较显然,贪心可证,然后就是个sb斜率优化d ...
- CSP-S 模拟测试92 题解
话说我怎么觉得我没咕多长时间啊,怎么就又落了20多场题解啊 T1 array: 根据题意不难列出二元一次方程,于是可以用exgcd求解,然而还有一个限制条件就是$abs(x)+abs(y)$最小,这好 ...
- CSP-S 模拟测试 51 题解
考试过程: 惯例先看一遍三道题,T1 一开始反应要求割点,但是这是有向图,肯定不能求割点,康了一下数据范围,有40%是树的,还不错,决定待会在打. 看T2 字符串题,完了我字符串最弱了,肯定只能打暴力 ...
- CSP-S 模拟测试 45 题解
由于咕掉的题解太多了,所以只能趁改完不动题的时间,来补补坑qwq,还是太弱了. 考试过程: 到新机房的第一次考试,貌似海星? 第一题一开始就觉得是个贪心,但以为所有小怪兽都要打完,所以想复杂了,但后来 ...
- [CSP-S模拟测试97]题解
A.小盆友的游戏 感觉题解解释的很牵强啊……还是打表找规律比较靠谱 对于每个人,它构造了一个期望函数$f(x)$,设它的跟班个数为$cnt[x]$,那么令$f(x)=2^{cnt[x]}-1$(??鬼 ...
- [CSP-S模拟测试96]题解
以后不能再借没改完题的理由不写题解了…… A.求和 求$\sum \sum i+j-1$ 柿子就不化了吧……这年头pj都不考这么弱智的公式化简了…… 坑点1:模数不定,可能没有2的逆元,那么只要先把乘 ...
- [CSP-S模拟测试92]题解
A.数列 显然每个数的答案是互相独立的,直接扩欧求解.我们需要最小化$ax+by=gcd(a,b)$中的$|x|+|y|$,而显然当x或y靠近0时答案可能最优,列个不等式求一下即可. 能$O(1)$千 ...
随机推荐
- 多线程学习:win32多线程编程基本概念(转)
一.定义: 1.进程和线程的区别 进程:是程序的执行过程,具有动态性,即运行的程序就叫进程,不运行就叫程序 ,每个进程包含一到多个线程.线程:系统中的最小执行单元,同一进程中有多个线程,线程可以共享资 ...
- php中连接tcp服务的三种方式
首先需要现有一个 tcp 服务,我们使用 php中的 socket 系列函数实现 <?php //创建socket套接字 $socket = socket_create(AF_INET, SOC ...
- Jmeter之JSON Path Extractor的使用(JSON-handle下载安装和使用)
jp@gc - JSON Path Extractor和“正则表达式提取器”使用效果一样. 他的作用单一,只提取json数据 jp@gc - JSON Path Extracto 变量名自己定义,js ...
- 关于工作单元模式——工作单元模式与EF结合的使用
工作单元模式往往和仓储模式一起使用,本篇文章讲到的是工作单元模式和仓储模式一起用来在ef外面包一层,其实EF本身就是工作单元模式和仓储模式使用的经典例子,其中DbContext就是工作单元,而每个Db ...
- idea的EasyCode使用
EasyCode可以自动根据表格生成:entity,dao,service,serviceImpl,controller 使用方法: 一.安装EasyCode插件: File-setting-Plug ...
- 使用Vue CLI脚手架搭建vue项目
本次是使用@vue/cli 3.11.0版本搭建的vue项目 1. 首先确保自己的电脑上的Node.js的版本是8.9版本或者以上 2. 全局安装vue/cli npm install @vue/cl ...
- Web框架概述——React.js
目前,在前端Web开发中,三大热门框架为React.js,Vue.js,Angular.js .当然,三大框架各有各的优缺点,这里就不多说了,下面我就针对前段时间所学的React框架做一下整体知识点的 ...
- django inclusion用法
概述: inclusion主要的是生成html标签, 返回的是一个字典,大分部跟simple_tag类似, simple_tag可返回任意类型的值 定义inclusion from django im ...
- web开发中的Cookie与Session技术
Cookie Cookie的由来 HTTP协议是无状态的,无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后 ...
- NSInvocation简单总结
(1)用法 NSInvocation是调用函数的另一种方式,它将调用者,函数名,参数封装到一个对象,然后通过一个invoke函数来执行被调用的函数,其思想就是命令者模式,将请求封装成对象. 例如,有这 ...