国庆集训1101+1103(未完成)

mac2025-07-16  5

吐槽诗(打油诗)

题面玄乎冗长,故事倒是挺好。 题解简单明了,尽显高深玄妙。 代码格式清晰,就是注释太少。 今天题目可订?你怕是在说笑!

yukikaze

#include<bits/stdc++.h> #define ll long long using namespace std; const int N = 5e5+5; char p[N]; int ans=0, lenp; inline char Cc(int a) {return char(a+'0');} inline int Ci(char a) {return a-'0';}//char和int的转换 int main() { scanf("%s", p+1); lenp = strlen(p+1); //输入 for(int i = 1; i <= lenp; i++) ans += Ci(p[i]); ans = 9-(ans%9); printf("%d\n", ans); //求删去的那个数 p[++lenp] = Cc(ans); ans = 0; for(int i = 1; i <= lenp; i++) { ans = ans*10+Ci(p[i]); p[i] = Cc(ans/9); ans %= 9; } //求x for(int i = 1; i <= lenp; i++) printf("%d", Ci(p[i])); puts("0"); //输出10x即s printf("0"); for(int i = 1; i <= lenp; i++) printf("%d", Ci(p[i])); //输出x即t return 0; }

tanikaze

shimakaze

#include <cstdio> #define ll long long; using namespace std; const ll mod = 1e9+7; const int N = 2e7+10; ll M(ll a){return a%mod;} int n, M; ll f[31][2], fac[N], inv[N], ans; ll pow(ll x,ll y){ ll c = 1; while(y){ if(y & 1) c = M( c*x ); b >>= 1; x = M( x*x ); } return c; } void prep() { fac[0] = 1; for(int i = 1; i <= n; i++) fac[i] = M( fac[i-1]*i ); inv[n] = pow(fac[n], mod-2); for(int i = n-1; i >= 1; i--) inv[i] = M( inv[i+1]*(i+1) ); }//处理阶乘及逆元 ll dfs(int left, int x, int y) { //left表示剩下的,还需要填多少数 ll tmpf[31][2]; for(int i = 0; i <= M; i++) for(int j = 0; j <= 1; j++) tmpf[i][j] = f[i][j]; ll tot = 0;//计算n中质因数数量至少x个的数 的数量 for(int i = x; i <= M; i++) for(int j = y; j <= 1; j++) tot += f[i][j], f[i][j] = 0; if (!x && !y){ for(int i = 0; i <= M; i++) for(int j = 0; j <= 1; j++) f[i][j] = tmpf[i][j]; return fac[tot]; }//边界 ll ans = 0; if (x) ans += dfs(left-tot, x-1, y);//gcd/2的情况 if (y) ans += dfs(left-tot, x, y-1);//gcd/3的情况 for(int i = 0; i <= M; i++) for(int j = 0; j <= 1; j++) f[i][j] = tmpf[i][j]; return M( M( fac[left-1]*inv[left-tot] ) * M( tot*ans ) ); //处理gcd不变的情况 //fac[left-1]*inv[left-tot] //等式转换一下,就是从left-tot+1乘到left-1,有tot个数填进去满足这个条件,就可以填1个,2个,3个…… } int main(){ scanf("%d", &n); prep(); f[0][0] = n; for(M = 1; f[M - 1][0]; M++) f[M][0] = f[M-1][0]>>1; M -= 2; //n可以分解出M+1个2 for(int i = 0; i <= M; i++) f[i][0] -= f[i+1][0];//减去重复,至少转换为恰好有 //(f[i][0]原先计算的是至少有i个2的数,减一减变成,恰好有i个2的数) f[0][1] = n / 3;//n中有0个2,1个3的数 for(int i = 1; i <= M-1; i++) f[i][1] = f[i-1][1]>>1; //n中有i个2,1个3的数,是n中有i-1个2,1个3的数除以2 for(int i = 0; i <= M-1; i++) f[i][1] -= f[i+1][1];//减去重复,至少转换为恰好有 for(int i = 0; i <= M; i++) f[i][0] -= f[i][1]; //n中有i个2,0个3的数 要减去 n中有i个2,1个3的数 ans = dfs(n, M, 0);//2^(M)的方案数 if (3*(1<<(M-1)) <= n) ans += dfs(n, M-1, 1); //如果2^(M)能够转换为另一种形式2^(M-1)*3,那么还要加上另外的方案数 printf("%lld\n", M(ans)); return 0; }

状压爆搜51分
#include<bits/stdc++.h> #define ll long long using namespace std; int T; ll n, k, ans; ll a[10000005]; const ll mod = 1e9+7; inline ll M(ll a){return a%mod;} inline ll add(ll a, ll b){return M(a+b);} inline ll sub(ll a, ll b){return M(a-b+mod);} inline ll mul(ll a, ll b){return M(a*b);} inline ll P(ll a,ll b){ll c=1;while(b){if(b&1)c=M(c*a);b>>=1;a=M(a*a);}return c;} inline void dfs(int num) { if(num == n+1) { int x1=(1<<k)-1, x2=0; for(int i = 1; i <= n; i++) { x1 = x1&a[i-1]; x2 = x2|a[i]; if(x2 == ((1<<k)-1)) return; } if(!x1 && x2!=((1<<k)-1)) ans++; return; } for(int j = 0; j <= (1<<k)-1; j++) {//货物 a[num] = j; dfs(num+1); } } int main() { scanf("%d", &T); while( T-- ) { scanf("%lld%lld", &n, &k); ans = 0; if(n>4 || k>4) puts("0"); else dfs(0), printf("%lld\n", M(ans)); } return 0; }
推公式正解AC
#include<bits/stdc++.h> #define ll long long using namespace std; int T; ll n, k, ans; const ll mod = 1e9+7; inline ll M(ll a){return a%mod;} inline ll sub(ll a, ll b){return M(a-b+mod);} inline ll mul(ll a, ll b){return M(a*b);} inline ll P(ll a,ll b){ll c=1;while(b){if(b&1)c=M(c*a);b>>=1;a=M(a*a);}return c;} int main() { scanf("%d", &T); while( T-- ) { scanf("%lld%lld", &n, &k); ans = mul( P(2,k), sub(P((P(2,n)-1), k),P((P(2,n)-2),k))); printf("%lld\n", ans); } return 0; }

dfs暴力枚举加特判55分
#include<bits/stdc++.h> #define ll long long using namespace std; const ll mod = 1e9+7; inline ll M(ll a){return a%mod;} inline ll add(ll a, ll b){return M(a+b);} inline ll sub(ll a, ll b){return M(a-b+mod);} inline ll mul(ll a, ll b){return M(a*b);} inline ll P(ll a,ll b){ll c=1;while(b){if(b&1)c=M(c*a);b>>=1;a=M(a*a);}return c;} const int N = 7e4; int a[N], b[N], n, m; bool bis[N], vis[N]; ll fac[N], inv[N], ans; void prep() { fac[0] = 1; for(int i = 1; i <= n; i++) fac[i] = mul(fac[i-1], i); }//处理阶乘 inline void dfs(int sum) { if(sum == n+1) { int mi = m; for(int i = 1; i <= n; i++) b[i] = a[i]; for(int i = 1, j; i <= n && mi; i<<=1){//跳的距离 j = 1; while(j < n && mi) { if(b[j] > b[j+i]) swap(b[j], b[j+i]); if(b[j]==1 && vis[b[j+i]]) return; if(vis[b[j+i]]) mi--; j += i<<1; } } ans++; } for(int i = 1; i <= n; i++) if(!bis[i]) a[sum]=i, bis[i]=1, dfs(sum+1), bis[i]=0; } inline ll work() { if(!m) return fac[n]; if(n-m <= 2) return 0; for(int i = 1, x; i <= m; ++i) { scanf("%d", &x); vis[x] = 1; } if(vis[2]) return 0; dfs(1); return M(ans); } int main() { scanf("%d%d", &n, &m); n = P(2, n); prep(); printf("%lld", work()); return 0; }

最新回复(0)