省选数学专题
难度升序排序(大概吧)。
[AGC016C] +/- Rectangle
签,虽然国集作业。
贪心是显然的,不说了,这里只考虑正数如何填。
如果
点此查看代码
#include<bits/stdc++.h> using namespace std; #define rep(i,s,t,p) for(int i = s;i <= t;i += p) #define drep(i,s,t,p) for(int i = s;i >= t;i -= p) #ifdef LOCAL auto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout); #else auto I = stdin,O = stdout; #endif using ll = long long;using ull = unsigned long long; using db = double;using ldb = long double; signed main(){ cin.tie(nullptr)->sync_with_stdio(false); int H,W,h,w; cin>>H>>W>>h>>w; if(H%h == 0 && W%w == 0) return cout<<"No\n",0; cout<<"Yes\n"; rep(i,1,H,1){ rep(j,1,W,1) if(i%h == 0 && j%w == 0) cout<<-(h*w-1)*500-1<<' '; else cout<<500<<' '; cout<<'\n'; } }
[JLOI2015] 骗我呢
反射容斥板子,写详细一点当反射容斥学习笔记了。
先考虑反射容斥是什么。
前置知识
在一个二维平面内,只能向右走或向上走,从
证明
发现每种合法路径必然走了
考虑如果有一条直线
显然答案就是
反射容斥
已经解决了只不允许碰撞一条线的,那么如果存在两条线(
考虑不合法的方案形如依次经过
显然答案为总方案数
关于本题
由
考虑优化这个柿子,会发现
感觉这个不好看,把它拉伸一下。(图是贺的)
发现就是从
点此查看代码
#include<bits/stdc++.h> using namespace std; #define rep(i,s,t,p) for(int i = s;i <= t;i += p) #define drep(i,s,t,p) for(int i = s;i >= t;i -= p) #ifdef LOCAL auto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout); #else auto I = stdin,O = stdout; #endif using ll = long long;using ull = unsigned long long; using db = double;using ldb = long double; const int N = 3e6 + 10,MN = 3e6,mod = 1e9 + 7; int n,m,fac[N],inv[N]; int qpow(int a,int b,int mod){ int res = 1; for(;b;b >>= 1,a = 1ll*a*a%mod) if(b & 1) res = 1ll*res*a%mod; return res; } int Inv(int a,int mod = mod){return qpow(a,mod-2,mod);} int C(int n,int m){if(n < 0 || m < 0 || m > n) return 0;return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;} void flip(int &a,int &b,int x){swap(a,b);a -= x;b += x;} signed main(){ cin.tie(nullptr)->sync_with_stdio(false); cin>>n>>m; fac[0] = 1;rep(i,1,MN,1) fac[i] = 1ll*fac[i-1]*i%mod; inv[MN] = Inv(fac[MN]); drep(i,MN-1,0,1) inv[i] = 1ll*inv[i+1]*(i+1)%mod; int ans = C(n*2+m+1,n); int x = n + m + 1,y = n; while(x >= 0 && y >= 0){ flip(x,y,1);ans -= C(x+y,x);ans += mod;ans %= mod; flip(x,y,-(m+2));ans += C(x+y,x);ans %= mod; } x = n + m + 1,y = n; while(x >= 0 && y >= 0){ flip(x,y,-(m+2));ans -= C(x+y,x);ans += mod;ans %= mod; flip(x,y,1);ans += C(x+y,x);ans %= mod; } cout<<ans<<'\n'; }
[AGC049D] Convex Sequence
模拟赛原,但是当时没改。
考虑将
假设最小值所在位置为
假设某一个合法方案的第一个最小值所在位置为
- 将
中的所有数设为 ,此操作只会再最开始进行一次。 - 选择一个
,将 加上 ,此操作可以进行任意次。 - 选择一个
,将 加上 ,此操作可以进行任意次。
当固定
注意
剩下的,发现就是一个完全背包问题,但是每次重新做的话复杂度是
点此查看代码
#include<bits/stdc++.h> using namespace std; #define rep(i,s,t,p) for(int i = s;i <= t;i += p) #define drep(i,s,t,p) for(int i = s;i >= t;i -= p) #ifdef LOCAL auto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout); #else auto I = stdin,O = stdout; #endif using ll = long long;using ull = unsigned long long; using db = long double;using ldb = long double; const int N = 1e5 + 10,mod = 1e9 + 7; int n,m,f[N]; signed main(){ cin.tie(nullptr)->sync_with_stdio(false); cin>>n>>m;f[0] = 1; auto Add = [&](int x){rep(i,x,m,1) f[i] = (f[i] + f[i-x])%mod;}; auto Del = [&](int x){drep(i,m,x,1) f[i] = (f[i] - f[i-x] + mod)%mod;}; if(n <= m) Add(n); for(ll i = 1;i < n && i*(i+1)/2 <= m; ++i) Add(i*(i+1)/2); int ans = 0; rep(i,1,n,1){ if(1ll*i*(i-1)/2 <= m) ans = (ans + f[m-i*(i-1)/2])%mod; if(1ll*(n-i)*(n-i+1)/2 <= m) Del((n-i)*(n-i+1)/2); if(1ll*i*(i+1)/2 <= m) Add(i*(i+1)/2); } cout<<ans<<'\n'; }
[ABC221H] Count Multiset
套路:多重集合转不下降序列。
先不考虑限制,设
- 将一个
填入,有 。 - 将全局加一,有
但是有相同的数不能出现超过
总的转移方程就是
前缀和优化可以做到
点此查看代码
#include<bits/stdc++.h> using namespace std; #define rep(i,s,t,p) for(int i = s;i <= t;i += p) #define drep(i,s,t,p) for(int i = s;i >= t;i -= p) #ifdef LOCAL auto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout); #else auto I = stdin,O = stdout; #endif using ll = long long;using ull = unsigned long long; using db = long double;using ldb = long double; const int N = 5e3 + 10,mod = 998244353; int n,m,f[N][N],g[N][N],sum[N][N]; signed main(){ cin.tie(nullptr)->sync_with_stdio(false); cin>>n>>m; rep(i,1,n,1){ if(i <= m) f[i][0] = 1; rep(j,1,n,1){ if(j >= i) g[i][j] = f[i][j] = f[i][j-i]; sum[i][j] = (sum[i-1][j] + g[i][j])%mod; f[i][j] = (0ll + f[i][j] + sum[i-1][j] - sum[max(0,i-m-1)][j] + mod) % mod; } } rep(i,1,n,1) cout<<g[i][n]<<'\n'; }
本文来自博客园,作者:CuFeO4,转载请注明原文链接:https://www.cnblogs.com/hzoi-Cu/p/18619812
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】