首页 > 其他分享 >CSP 模拟 28

CSP 模拟 28

时间:2024-09-06 21:13:35浏览次数:8  
标签:ch frac int sum 28 mid long CSP 模拟

T1 喜剧的迷人之处在于

将 \(a\) 分解质因数,容易找到满足 \(ab\) 为平方数的最小 \(b\),然后需要让 \(b\) 乘上一个平方数后在 \([L,R]\) 中,二分找即可。

T2 镜中的野兽

\[\begin{aligned} &f(x)=\sum\cdots\sum[\gcd=1,\text{lcm}=x]\\ &g(x)=\sum\cdots\sum[\gcd\mid x,\text{lcm}=x]\\ &h(x)=\sum\cdots\sum[\gcd\mid x,\text{lcm}\mid x] \end{aligned} \]

外层枚举 \(gcd\) 后求 \(f(\frac{m}{gcd}-1)\) 即可,\(Q(x)\) 表示 \(x\) 的约数个数。

\[\begin{aligned} &h(x)=\operatorname{C}_{Q(x)}^{n}\\ &h(x)=\sum_{d\mid x}g(d)\\ &g(x)=\sum_{d\mid x}\mu(\frac{x}{d})h(d)\\ &g(x)=\sum_{d\mid x}f(d)\\ f(x)&=\sum_{d\mid x}\mu(\frac{x}{d})g(d)\\ &=\sum_{d\mid x}\mu(\frac{x}{d})\sum_{e\mid d}\mu(\frac{d}{e})h(e) \end{aligned} \]

直接枚举三层约数求即可,题解说时间复杂度上界 \(O(d(m)(d(m)^2+\sqrt m))\),但是很松。
也可以把最外层的莫反换成容斥,设 \(W(x)\) 表示 \(\gcd\) 是 \(x\) 的倍数的方案数,\(W(i)=g(\frac{x}{i}),x=\prod_{i=1}^{cnt}p_i^{c_{i}},f(x)=g(x)-W(p_1)\cdots\cup W(p_{cnt})\),处理好 \(g(x)\) 之后,直接对后面的并集进行容斥即可。时间复杂度一样,但是不知道为什么跑的比上面慢很多。

#include<bits/stdc++.h>
#define int long long
typedef long long ll;
typedef unsigned long long ull;
inline int read(){char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;}
const int N=1e5+10;
int n,m,mod,ans,jc[N],ny[N],f[N],u[N],p[N],tot;
std::vector<int> d[N];
bool vis[N];
inline int mo(int x){return x<0?(x%mod+mod)%mod:(x<mod?x:x%mod);}
inline int qpow(int a,int b){int res=1;for(;b;b>>=1,a=mo(a*a))if(b&1)res=mo(res*a);return res;}
inline int C(int x,int y){if(x<y)return 0;return jc[x]*ny[y]%mod*ny[x-y]%mod;}
inline void init(){
	int mx=1e5;
	for(int i=1;i<=mx;++i)jc[i]=mo(jc[i-1]*i);
	ny[mx]=qpow(jc[mx],mod-2);for(int i=mx-1;i;--i)ny[i]=mo(ny[i+1]*(i+1));
}
inline int F(int x){
	int res=0;
	for(int i=1;i*i<=x;++i){
		if(x%i==0){
			res+=1+(i*i!=x);
		}
	}
	return C(res,n);
}
inline int U(int x){
	int res=0;
	for(int i=2;i*i<=x;++i){
		if(x%i==0){
			res++;
			x/=i;
			if(x%i==0)return 0;
		}
	}
	res+=(x!=1);
	if(res&1)return -1;else return 1;
}
inline int G(int x){
	int res=0;
	for(int i=1;i*i<=x;++i){
		if(x%i==0){
			int j=x/i;
			if(U(j))res=mo(res+U(j)*F(i));
			if(i!=j&&U(i))res=mo(res+U(i)*F(j));
		}
	}
	return res;
}
inline void work(int x){
	if(!x)return ;
	int res=0;
	for(int i=1;i*i<=x;++i){
		if(x%i==0){
			int j=x/i;
			if(U(j))res=mo(res+U(j)*G(i));
			if(j!=i&&U(i))res=mo(res+U(i)*G(j));
		}
	}
	ans=mo(ans+res);
}
signed main(){
	// freopen("in.in","r",stdin);freopen("out.out","w",stdout);
	std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
	n=read(),m=read(),mod=read();jc[0]=ny[0]=1;
	init();
	for(int i=1;i*i<=m;++i){
		if(m%i==0){
			int j=m/i;
			work(i-1);if(i!=j)work(j-1);
		}
	}
	std::cout<<ans<<'\n';
}

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

trick 题,设 \(pre_i\) 表示以位置 \(i\) 结尾从左往右构成上升序列的方案数,\(suc_i\) 表示以位置 \(i\) 结尾从右往左构成上升序列的方案数,两者的处理方法相同。
处理完之后,所有合法答案数量为 \(\sum_i^npre_i\cdot suc_i\),简单观察后发现一个合法序列中的 \(t\) 值是连续的一段相同的数,所以上面的答案算重,考虑容斥,钦定序列中的第一个 \(t\) 才有贡献,则上面的答案需要减去 \(\sum_i^npre_{fm_{a_i}}suc_i\),其中 \(fm_i\) 表示 \(i\) 之前出现过的位置,前缀和处理后整个过程的复杂度为 \(\mathcal{O}(n)\),所以现在只需要考虑处理 \(pre\) 和 \(suc\)。
首先有一个显然的 \(\mathcal{O}(2^mn)\) 做法,设 \(f_i\) 表示到当前位置,以 \(i\) 的子集结尾的构成上升序列的方案数,然后枚举并集来更新,这样的更新是 \(\mathcal{O}(2^m)\),查询只有 \(\mathcal{O}(1)\)。
考虑将更新和查询的复杂度平衡,设 \(f_{i,j}\) 表示到当前位置,以前半部分是 \(i\),后半部分为 \(j\) 的子集的数结尾的构成上升序列的方案数,此时的更新和查询都是 \(\mathcal{O}(2^{(\frac{m}{2})})\),整个算法复杂度为 \(\mathcal{O}(2^{\frac{m}{2}}n)\)。

#include<bits/stdc++.h>
#define int long long
typedef long long ll;
typedef unsigned long long ull;
inline int read(){char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;}
const int N=1.2e6+10,mod=1e9+7;
int f[2050][2050],n,a[N],pre[N],suc[N],m,n1,n2,last[N],ans;
inline int mo(int x){return x<0?(x%mod+mod)%mod:(x<mod?x:x%mod);}
inline void insert(int x,int k){
	int fi=x>>n1,se=x^(fi<<n1);
	int zc=~se;zc=zc^(zc>>n1<<n1);
	for(int s=zc;;s=(s-1)&zc){
		f[fi][se|s]=mo(f[fi][se|s]+k);
		if(!s)break;
	}
}
inline int query(int x){
	int fi=x>>n1,se=x^(fi<<n1),res=0;
	for(int s=fi;;s=(s-1)&fi){
		res=mo(res+f[s][se]);
		if(!s)break;
	}
	return res;
}
signed main(){
	// freopen("in.in","r",stdin);freopen("out.out","w",stdout);
	std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
	n=read();m=read();n1=(m-1)/2+1,n2=m/2;
	for(int i=1;i<=n;++i)a[i]=read();
	for(int i=1;i<=n;++i){
		pre[i]=mo(1+query(a[i]));
		insert(a[i],pre[i]);
	}
	memset(f,0,sizeof(f));std::reverse(a+1,a+n+1);
	for(int i=1;i<=n;++i){
		suc[i]=mo(1+query(a[i]));
		insert(a[i],suc[i]);
	}std::reverse(suc+1,suc+n+1);
	std::reverse(a+1,a+n+1);
	for(int i=1;i<=n;++i){
		ans=mo(ans+pre[i]*suc[i]);
		ans=mo(ans-last[a[i]]*suc[i]);
		last[a[i]]=mo(last[a[i]]+pre[i]);
	}
	std::cout<<ans<<'\n';
}

T4 Baby Doll

q-analog

标签:ch,frac,int,sum,28,mid,long,CSP,模拟
From: https://www.cnblogs.com/Ishar-zdl/p/18401019

相关文章

  • CF1307(模拟赛记录)
    比赛页面偶然发现一道做过的G;C的罚时:没开longlong,谨记。然后一个小时没想出E……E题面:在一年成功的牛奶生产后,FarmerJohn奖励他的奶牛们它们最喜欢的美味的草。在田里有\(n\)个单位的排成一行的草,每个单位的草有甜味\(s_i\)。FarmerJohn有\(m\)头奶牛,每只都......
  • 828华为云征文|华为云Flexus X实例部署安装HivisionIDPhoto一个轻量级的AI证件照制作算
    背景最近有一个开源项目非常火,就是HivisionIDPhotos一个轻量级的AI证件照制作算法github仓库https://github.com/Zeyi-Lin/HivisionIDPhotos由于最近华为云最近正在举办B2B企业节,FlexusX实例的促销力度非常大。所以购买了一个FlexusX实例。4核12G。准备安装一个,试一......
  • CSP-2024 第一次
    A分解\(a\)之后可以轻松找到最小的\(b\)满足\((a,b)\)是好的,而其他的\(b\)一定是最小的\(b\)的完全平方数倍。B暴力大战(为啥\(d^3(m)\)甚至\(d^4(m)\)能轻松过1e9啊,赛时以为\(d(m)=\Theta(\sqrtm)\),\(d^3(m)=\Theta(m\sqrtm)\)就没敢写,只写了\(O(m\log......
  • 洛谷 P5658 [CSP-S2019] 括号树
    洛谷P5658[CSP-S2019]括号树题意给定一棵树,每个点有一个括号(或)。定义\(s_i\)表示根节点到\(i\)每个点的括号组成的序列。求每个\(s_i\)中合法括号子串的个数\(f_i\)。思路定义\(g_i\)表示\(s_i\)中以\(i\)结尾的合法括号子串的个数。有\(f_i=f_{fa_......
  • 2024.9.6 模拟赛
    A对于一个子矩阵\((x_1,y_1),(x_2,y_2)\),其元素和为\(\sum_{i=x_1}^{x_2}\sum_{j=y_1}^{y_2}S_i\cdotS_j=(\sum_{i=x_1}^{x_2}S_i)(\sum_{j=y_1}^{y_2}S_j)\),\(O(n^2)\)枚举一下\(S\)的所有子区间的和放进一个桶里再检验一下即可。即对于一个子区间和为\(S_1\),需要累加和......
  • CF1534(模拟赛记录)
    比赛页面ABCD都打的可以,然而E的+10直接葬送了大概率过的F1……先猜了个\(n-k+1\)的结论,但是没有写搜索查正确性(事实上确实不正确),于是两次罚时,第一次是交互格式错了。然后又猜了个\(\min(n-k+1,(n-1)/(k-1))\)的结论,过了几个小的搜索数据(\(n\le6\))的,大一点的没跑,于......
  • 2024.9.6 CF1307 模拟赛记录
    A:各捆干草间互相独立,所以优先移动距\(1\)近的。点击查看代码#include<bits/stdc++.h>#defineintlonglong#definepsbkpush_back#definefstfirst#definescdsecond#defineumapunordered_map#definepqueuepriority_queue#definevcvector#defineendl'\n'......
  • C语言——使用回调函数模拟实现qsort
    同学们还记得之前我们已经学过一种排序方法叫“冒泡排序“嘛。代码直接附上咯voidbubble_sort(intarr[],intsz){ inti=0;//趟数 for(i=0;i<sz-1;i++) { intj=0; for(j=0;j<sz-i-1;j++) { if(arr[j]>arr[j+1]) { inttmp=......
  • 『模拟赛』CSP-S模拟1
    Rank1BADA.喜剧的迷人之处在于签。正好早上还在改一个要分解质因数的题,所以一眼就出思路了。首先将\(a\)的平方因子全部除去,剩下的就是\(b\)必须的因数,即若设将平方因子全部除去后的\(a\)为\(a'\),则\(b\)应表示为\(a'\timesx^2\),从\(L\)这个下界开始只用找......
  • 使用flask进行Mock Server模拟接口操作及问题解决
    1.flask介绍flask是一个轻量级的pythonweb微框架2.MockServer介绍MockServer是一个开源的模拟服务器,它可以定义和记录API交互,支持各种http方法(get、post、put、delete),可以自定义响应内容,例如返回静态文件可以使用flask来搭建一个mock模拟服务3.模拟接口先安装flaskpip......