题解:
首先subtask1直接状压暴力就好
subtask2我的处理和题解不太一样
仍然正向考虑
设i的时候有最高位为j,那么这个时候数一定越大越好(这个比较好yy)
然后$f[i][j]$搞个高精度dp就可以了
复杂度$(n^3/64)$
我懒得手写了。。就写了$n^3$的
还有bitset本地开O2 0.5s 不开O2 32s 真可怕
subtask4
显然我们会先用1,然后到一定时候为了保证位数有0就得用
#include <bits/stdc++.h> using namespace std; #define rint register int #define IL inline #define rep(i,h,t) for (int i=h;i<=t;i++) #define dep(i,t,h) for (int i=t;i>=h;i--) bitset<510> f[600][600]; const int N=2e6; char c[N]; #define te bitset<510> IL bool pd1(te B,int k) { rep(i,1,k) if (B[i]!=1) return(0); return(1); } IL te plu(te B1) { te B=B1; int i; for (i=1;i<=500;i++) if (B[i]==0) break; B[i]=1; i--; for (;i>=1;i--) B[i]=0; return B; } bool pd(te x,te y) { for (int i=500;i>=1;i--) { if (x[i]>y[i]) return 0; if (x[i]<y[i]) return 1; } return 0; } IL void maxa(te &a,te b) { if (pd(a,b)) a=b; } te ans; int n,m; namespace subtask4{ int f[N]; void solve() { dep(i,n,1) if (c[i]=='*') f[i]=f[i+1]+1; else f[i]=f[i+1]; bool tt=0; int cnt=0,cnt3=0; rep(i,1,n) { if (c[i]=='+') { cout<<1; tt=1; cnt++; cnt3=0; } else { cnt3++; if (cnt3>1&&tt&&f[i]<m-cnt) { cout<<0; cnt++;} } if (cnt==m) {break;} } if (tt&&cnt!=m&&cnt3>0) cout<<0; if (!tt) cout<<0; } }; int main() { freopen("1.in","r",stdin); freopen("2.out","w",stdout); ios::sync_with_stdio(false); cin>>n>>m; rep(i,1,n) cin>>c[i]; if (n<=500&&m<=500) { rep(i,1,n) rep(j,0,m) { if (c[i]=='+') { if (j&&pd1(f[i-1][j-1],j-1)) f[i][j][j]=1; if (!pd1(f[i-1][j],j)) maxa(f[i][j],plu(f[i-1][j])); } else { if (j) f[i][j]=f[i-1][j-1]<<1; } maxa(f[i][j],f[i-1][j]); } int pos=1; dep(i,500,1) maxa(ans,f[n][i]); dep(i,500,1) if (ans[i]) { pos=i; break;} dep(i,pos,1) cout<<ans[i]; } else { subtask4::solve(); } return 0; }
然后正解其实就是先做一个转化
把*后面相邻的+变成乘前面的+
于是这样就变成subtask4