CF1808E Minibuses on Venus 智商毁灭记
都要考省选了大脑还在这里下线
场上看到这道题很快推出了 为奇数的搞法,发现可以直接做到 ,一阵狂喜然后肝起了 E3,结果 E1 都没过。
事实上这道题可以直接做到 ,不过需要细致的观察自己场上推的式子。
题意:
对长度为 ,值域为 的整数数组 计数,要求 满足 。
思路:
这道题的分析频繁用到了一次同余方程式的有解性分析,也就是说对于 ,当 时有 个解,否则无解。
显然可以先枚举一波 ,那么题目的条件相当于 。
是奇数时上述方程始终有唯一解,题目的限制相当于强制 必须出现。
考虑计数强制 必须不出现,然后对着这个限制上容斥,钦定 至少出现了 次。
剩下的部分如果 ,那么通过调整最后一个数的取值总可以满足 。如果 那么只需要判断 是否同余于 。
方案数就是:
对于所有 ,考虑 的有解性,总方案数就是:
是偶数时更复杂一点。这时 在 是偶数时有两个解,记为 和 。
现在要求序列中这两个解必须至少出现一个,那么考虑计数两个解都没有出现的方案数。
依然考虑对于“没有出现”这一限制施加容斥,枚举 , 的出现次数。
用三项式定理做一下右边的部分,就是:
左边的线性同余方程的解是一个等差数列,相当于是要组合数等差数列位置的和。这里场后被 zhy 教育了,可以直接循环卷积快速幂 做。
然而这个同余式太有性质了!整理一下:
也就是:
右边只与 奇偶性有关!左边只与 有关!而众所周知组合数奇数偶数位置求和都是 。
我们现在只需要求出满足 或 的 的个数。
注意 本来就满足 可以统一写成 , 的个数就是 。
总的式子就是:
这道题就做完了。
#include <cstdio> using namespace std; template<typename T> T read(){ char c=getchar();T x=0; while(c<48||c>57) c=getchar(); do x=(x<<1)+(x<<3)+(c^48),c=getchar(); while(c>=48&&c<=57); return x; } typedef long long ll; ll n;int k,p; int qp(int a,ll b){ int res=1; b%=(p-1); while(b){ if(b&1) res=(ll)res*a%p; a=(ll)a*a%p;b>>=1; } return res; } ll gcd(ll a,ll b){ if(!b) return a; return gcd(b,a%b); } void inc(int &x,int v){if((x+=v)>=p) x-=p;} void dec(int &x,int v){if((x-=v)<0) x+=p;} int main(){ n=read<ll>();k=read<int>();p=read<int>(); if(n==1){puts("1");return 0;} if(k&1){ int g=gcd(n-2,k); int res=qp(k,n); dec(res,qp(k-1,n)); if(n&1) inc(res,g-1); else dec(res,g-1); printf("%d\n",res); } else{ int g=gcd(n-2,k>>1); int res=qp(k,n); dec(res,qp(k-2,n)); inc(res,qp(p-2,n)); if(res&1) res=(res+p)>>1; else res>>=1; if(n&1) inc(res,(ll)qp(2,n-1)*g%p); else dec(res,(ll)qp(2,n-1)*g%p); printf("%d\n",res); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现