T1 如何优雅的送分

考虑式子的实际意义。\(2^{f_n}\)实际上就是枚举\(n\)质因子的子集。令\(k\)为这个子集中数的乘积,就可以将式子转化为枚举\(k\),计算\(k\)的贡献。

不难得出\(k\)一定没有平方因子,那么枚举\(k\)就可以写为枚举\(\left \{ \mu^2(d)|d\in N^* \right \}\),即:

\[2^{f_i}=\sum_{k=1}^n\mu^2(k)
\]

发现有\(\mu^2(d)=\sum_{k^2|d}\mu(k)\),证明时考虑\(d\)有几个平方因子。当没有时,\(k\)只能取\(1\)。否则令\(x\)为它的平方因子个数,有:

\[\sum_{k^2|d}\mu(k) =\sum_{d=0}^x(-1)^d\binom{x}{d}
\]

发现它就是个二项式定理,即\((-1+1)^x=0\)。于是等式成立。

于是接下来一波合适变换整成整除分块的形式,求答案即可。

\[\begin{aligned}
\sum_{i=1}^n2^{f_i} &=\sum_{i=1}^n\sum_{d|i}\mu^2(d)
\\ &=\sum_{i=1}^n\sum_{d|i}\sum_{k^2|d}\mu(k)
\\ &=\sum_{k=1}^n\sum_{k^2|d}\left\lfloor \frac{n}{d} \right\rfloor
\\ &=\sum_{k=1}^n\mu(k)\sum_{i=1}^{\left\lfloor\frac{n}{k^2}\right\rfloor}\left\lfloor\frac{n}{k^2i}\right\rfloor
\\ &=\sum_{k=1}^n\mu(k)S(\left\lfloor\frac{n}{k^2}\right\rfloor)
\end{aligned}
\]

其中\(S(n)=\sum_{i=1}^n\left\lfloor\frac{n}{i}\right\rfloor\),枚举\(k\),整除分块求\(S\)即可。时间复杂度\(\Theta(\sqrt n \ln n)\)。

数学题题解写着真累

\(code:\)

T1

#include<bits/stdc++.h>
#define int long long
using namespace std; namespace IO{
typedef long long LL;
auto read=[]()->int{
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
};
auto write=[](LL x,int sp)->void{
char ch[20]; int len=0;
if(x<0){ x=~x+1; putchar('-'); }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
};
auto ckmax=[](int& x,int y)->void{ x=x<y?y:x; };
auto ckmin=[](int& x,int y)->void{ x=x<y?x:y; };
} using namespace IO; const int p=1e9+7;
int n,ext,ans,cnt,pri[1000010],mu[1000010];
bool vis[1000010];
void get(){
mu[1]=1;
for(int i=2;i<=ext;i++){
if(!vis[i]) pri[++cnt]=i, mu[i]=-1;
for(int j=1;j<=cnt&&pri[j]*i<=ext;j++){
vis[pri[j]*i]=1;
if(!(i%pri[j])) break;
mu[pri[j]*i]=-mu[i];
}
}
} int calc(int N){
int l=1,r,res=0;
while(l<=N){
r=N/(N/l);
(res+=(N/l)*(r-l+1))%=p;
l=r+1;
}
return res;
} signed main(){
freopen("elegant.in","r",stdin);
freopen("elegant.out","w",stdout);
n=read(); ext=sqrt(n); get();
for(int i=1;i<=ext;i++)
(ans+=p+mu[i]*calc(n/(i*i)))%=p;
return write(ans,'\n'),0;
}


T2 阴阳

\(set\)大暴力,记黑点。显然被卡了,正解太神仙,暴力没啥意思,不放代码了。

T3 你猜是不是找规律

令\(f_{i,j}\)为长度为\(i\)的排列,最少交换\(j\)次合法的方案数。转移时考虑新一个数是否放在最后,有

\[f_{i,j}=f_{i-1,j}+(i-1)\times f_{i-1,j-1}
\]

非常感性地发现\(f_{n,k}\)为关于\(n\)的\(2k-1\)次多项式,答案,即\(\sum_{i=0}^k f_{n,i}\),为关于\(n\)的\(2k\)次多项式。拉格朗日插值即可。

\(code:\)

T3

#include<bits/stdc++.h>
#define int long long
using namespace std; namespace IO{
typedef long long LL;
auto read=[]()->int{
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
};
auto write=[](LL x,int sp)->void{
char ch[20]; int len=0;
if(x<0){ x=~x+1; putchar('-'); }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
};
auto ckmax=[](int& x,int y)->void{ x=x<y?y:x; };
auto ckmin=[](int& x,int y)->void{ x=x<y?x:y; };
} using namespace IO; const int NN=3010,p=1e9+7;
int n,k,ans,f[NN];
int x[NN<<1],y[NN<<1];
int qpow(int a,int b){
int res=1;
while(b){
if(b&1) res=res*a%p;
a=a*a%p;
b>>=1;
}
return res;
} inline int langrange(int num,int xx){
int res=0; xx%=p;
for(int i=1;i<=num;i++){
int s1=y[i]%p,s2=1;
for(int j=1;j<=num;j++)
if(i!=j) s1=s1*(xx-x[j]+p)%p, s2=s2*(x[i]-x[j]+p)%p;
(res+=s1*qpow(s2,p-2)%p)%=p;
}
return res;
} signed main(){
freopen("guess.in","r",stdin);
freopen("guess.out","w",stdout);
n=read(); k=read();
x[1]=1; y[1]=1; f[0]=1;
for(int i=2;i<=2*k+1;i++){
x[i]=i;
for(int j=k;j;j--) (f[j]+=(i-1)*f[j-1])%=p;
for(int j=0;j<=k;j++) (y[i]+=f[j])%=p;
}
return write(langrange(2*k+1,n),'\n'),0;
}


T4 小说

题解说得很清楚。

\(01\)退背包:记\(f\)为原\(01\)背包方案数,\(g\)为强制第\(i\)件物品不选的方案数。有

\[g_k=\begin{cases} f_k & k<v_i \\ f_k-g_{k-v_i} &k\geq v_i \end{cases}
\]

\(code:\)

T4

#include<bits/stdc++.h>
#define int long long
using namespace std; namespace IO{
typedef long long LL;
auto read=[]()->int{
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
};
auto write=[](LL x,int sp)->void{
char ch[20]; int len=0;
if(x<0){ x=~x+1; putchar('-'); }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
};
auto ckmax=[](int& x,int y)->void{ x=x<y?y:x; };
auto ckmin=[](int& x,int y)->void{ x=x<y?x:y; };
} using namespace IO; const int NN=110,WW=1401000,p=998244353;
int n,mx,pos,ans,sum,tot,v[NN];
int f[WW],g[WW]; void work(int I){
int res=0;
memset(g,0,sizeof(g)); g[0]=1;
for(int i=1;i<=sum;i++)
if(i<v[I]) g[i]=f[i];
else g[i]=(f[i]-g[i-v[I]]+p)%p;
for(int i=1;i<=sum;i++)
res+=(bool)g[i];
if(res>mx) mx=res,pos=I;
} signed main(){
freopen("novel.in","r",stdin);
freopen("novel.out","w",stdout);
n=read(); f[0]=1;
for(int i=1;i<=n;i++)
sum+=(v[i]=read());
sort(v+1,v+n+1);
for(int i=1;i<=n;i++)
for(int j=sum;j>=v[i];j--)
(f[j]+=f[j-v[i]])%=p;
for(int i=1;i<=n;i++) work(i);
tot=sum-v[pos]; write(v[pos],' ');
memset(f,0,sizeof(f)); f[tot]=1;
for(int i=1;i<=n;i++) if(i!=pos){
for(int j=tot+tot;j>=v[i];j--)
f[j]|=f[j-v[i]];
for(int j=0;j<=tot+tot-v[i];j++)
f[j]|=f[j+v[i]];
}
for(int i=1;i<=tot;i++)
if(!f[i+tot]) return write(i,'\n'),0;
return write(tot+1,'\n'),0;
}


2021.10.12考试总结[NOIP模拟75]的更多相关文章

  1. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

  2. 2021.8.12考试总结[NOIP模拟37]

    T1 数列 考场上切掉的简单题. $a$,$b$与数列中数的正负值对答案无关.全当作正数计算即可. $exgcd$解未知数系数为$a$,$b$,加和为$gcd(a,b)$的不定方程组,再枚举每个数.如 ...

  3. 2021.10.7考试总结[NOIP模拟71]

    信心赛,但炸了.T3SB错直接炸飞,T4可以硬算的组合数非要分段打表求阶乘..T2也因为一个细节浪费了大量时间.. 会做难题很好,但首先还是要先把能拿的分都拿到. T1 签到题 结论:总可以做到对每个 ...

  4. 2021.10.15考试总结[NOIP模拟77]

    \(n=40\)考虑\(meet \;in \;the \;middle\) 某个元素有关的量只有一个时考虑转化为树上问题 对暴力有自信,相信数据有梯度 没了 UPD:写了个略说人话的. T1 最大或 ...

  5. 2021.10.18考试总结[NOIP模拟76]

    T1 洛希极限 不难发现每个点肯定是被它上一行或上一列的点转移.可以预处理出每个点上一行,上一列最远的能转移到它的点,然后单调队列优化. 预处理稍显ex.可以用并查集维护一个链表,记录当前点之后第一个 ...

  6. 2021.10.11考试总结[NOIP模拟74]

    T1 自然数 发现\(mex\)是单调不降的,很自然地想到用线段树维护区间端点的贡献. 枚举左端点,用线段树维护每个右端点形成区间的\(mex\)值.每次左端点右移相当于删去一个数. 记\(a_i\) ...

  7. 2021.10.9考试总结[NOIP模拟72]

    T1出了个大阴间题 状压\(DP\),记当前状态的代价和与方案数.状态\(\Theta(2^nn)\),转移\(\Theta(n)\). 发现每个状态的最大值只会是所选集合的\(max\)或加一.于是 ...

  8. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  9. 2021.6.29考试总结[NOIP模拟10]

    T1 入阵曲 二位前缀和暴力n4可以拿60. 观察到维护前缀和时模k意义下余数一样的前缀和相减后一定被k整除,前缀和维护模数,n2枚举行数,n枚举列, 开一个桶记录模数出现个数,每枚举到该模数就加上它 ...

随机推荐

  1. 法术迸发(Spellburst)

    描述 法术迸发 (EN:Spellburst ) 是一种在<通灵学园>中加入的关键字异能,在玩家打出一张法术牌后触发,只能触发一次. 若随从在法术结算过程中死亡,则不会触发效果 思路 首先 ...

  2. RSTP

    一.STP协议的缺点,存在的问题 STP 协议工作时间收敛慢,响应时间长---------->RSTP 原始的802.1d(stp)不支持多个vlan---->(PVST===>把一 ...

  3. python语言介绍及安装

    Python语言简介 Python是什么语言 Python是一种解释型的.可移植的.开源的脚本. 什么是计算机编程 计算机程序:为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合 如何 ...

  4. 【PHP数据结构】图的应用:最小生成树

    在学习了图的基本结构和遍历方式后,我们再继续地深入学习一些图的基本应用.在之前的数据结构中,我们并没接触太多的应用场景,但是图的这两类应用确是面试或考试中经常出现的问题,而且出现的频率还非常高,不得不 ...

  5. 使用OPCache提升PHP的性能

    对于 PHP 这样的解释型语言来说,每次的运行都会将所有的代码进行一次加载解析,这样一方面的好处是代码随时都可以进行热更新修改,因为我们不需要编译.但是这也会带来一个问题,那就是无法承载过大的访问量. ...

  6. PHP执行数据库定时备份 和手动还原

    一 备份数据库 我的这个是在TP5上,其实不在TP5也可以 逻辑: 1 首先在自己电脑的cmd命令上测试备份数据库,成功才能往下进行所以得到 C:/luanxiede/mysql-5.7/bin/my ...

  7. Linux系列(24) - chmod

    前言 在Unix和Linux的中,每个文件(文件夹也被看作是文件)都有三种权限:读.写.运行. 被授予权限的用户身份有三种:当前文件的拥有者,与拥有者属于同组者(同一个group),其他人 hello ...

  8. 为什么Charles中的中文展示成数字、英文字符串

    在使用charles抓包时,可能非看到如下图的字符串: 为什么会出现这样的字符串? 我们看到的汉字.字母,对电脑来说并不长这样,而是用二进制表示的(显然--),为了统一标准,老外发明了"字符 ...

  9. 《使用Jmeter进行批量发送http请求》

    本文主要针对批量接口发送数据 一:接口测试的环境准备 1:JDK的安装:网上下载即可>1.6.0版本以上 2:jemeter工具的下载 (免安装):网上下载即可 3:插件的下载安装地址:http ...

  10. english note [6.3to6.9]

    6.3 http://www.51voa.com/VOA_Special_English/pakistan-town-struggles-with-rise-in-hiv-infections-821 ...