1806做题记录 I
BZOJ5340/Luogu P4564 [CTSC2018] 假面
概率与期望、动态规划
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define clr(x) memset(x,0,sizeof(x)) 5 #define mod 998244353 6 #define MN 203 7 using namespace std; 8 inline int in(){ 9 int x=0;bool f=0; char c; 10 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 11 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 12 return f?-x:x; 13 } 14 int f[MN][MN],g[MN],p[MN],res[MN],pos[MN],m[MN],inv[MN]; 15 int n,q,k,op,ps,u,v,ans; 16 inline int qpow(int x,int k){ 17 int res=1; 18 while (k){ 19 if (k&1) res=(1ll*res*x)%mod; 20 x=(1ll*x*x)%mod;k>>=1; 21 }return res; 22 } 23 inline void dp(int x,int v){ 24 f[x][0]=(1ll*f[x][1]*v+f[x][0])%mod; 25 for (int i=1;i<=m[x];++i) 26 f[x][i]=((1ll*f[x][i+1]*v)%mod+(1ll*f[x][i]*(mod+1-v))%mod)%mod; 27 } 28 inline void query(){ 29 clr(g);clr(p);clr(res);g[0]=1; 30 for (int i=1;i<=k;++i) 31 for (int j=i;j>=0;--j) 32 if (!j) g[j]=(1ll*g[j]*f[pos[i]][0])%mod; 33 else g[j]=((1ll*g[j]*f[pos[i]][0])%mod+(1ll*g[j-1]*(mod+1-f[pos[i]][0]))%mod)%mod; 34 for (int i=1;i<=k;++i){ 35 if (f[pos[i]][0]){ 36 int ivm=qpow(f[pos[i]][0],mod-2); 37 for (int j=0;j<k;++j){ 38 if (j) p[j]=(1ll*(g[j]+mod-(1ll*p[j-1]*(mod+1-f[pos[i]][0]))%mod)*ivm)%mod; 39 else p[j]=(1ll*g[j]*ivm)%mod; 40 res[i]=(res[i]+(1ll*inv[j+1]*p[j])%mod)%mod; 41 } 42 }else{ 43 for (int j=0;j<k;++j) 44 res[i]=(res[i]+(1ll*inv[j+1]*g[j+1])%mod)%mod; 45 } 46 res[i]=(1ll*res[i]*(mod+1-f[pos[i]][0]))%mod; 47 } 48 for (int i=1;i<=k;++i) printf("%d ",res[i]);puts(""); 49 } 50 int main() 51 { 52 n=in(); 53 for (int i=1;i<=n;++i){ 54 m[i]=in();f[i][m[i]]=1; 55 inv[i]=qpow(i,mod-2); 56 }q=in(); 57 for (int i=1;i<=q;++i){ 58 op=in(); 59 if (!op){ 60 ps=in();u=in();v=in(); 61 dp(ps,(1ll*u*qpow(v,mod-2))%mod); 62 }else{ 63 k=in(); 64 for (int i=1;i<=k;++i) pos[i]=in();query(); 65 } 66 } 67 for (int i=1;i<=n;++i){ 68 ans=0; 69 for (int j=1;j<=m[i];++j) ans=(ans+(1ll*f[i][j]*j)%mod)%mod; 70 printf("%d ",ans); 71 }return 0; 72 }
BZOJ 5343/Luogu P4602 [CTSC2018]混合果汁
对于每种果汁按美味度从大到小排序,以价格为下标,以每种果汁为版本建立可持久化线段树,维护果汁的体积和及价格和。
对于每种需求,二分查找果汁对应的版本,在该版本的线段树上二分,判断是否满足对果汁体积要求的情况下满足对价格的要求。
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ll long long 5 #define mid ((l+r)>>1) 6 #define MM 2300005 7 #define MN 100005 8 using namespace std; 9 inline ll in(){ 10 ll x=0;bool f=0;char c; 11 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 12 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 13 return f?-x:x; 14 } 15 struct st{ 16 int d,p; 17 ll l; 18 }a[MN]; 19 int L[MM],R[MM],rt[MN]; 20 ll sum[MM],cst[MM],g,k; 21 int n,m,mx,cnt,res; 22 inline bool cmp(st x,st y){return x.d>y.d;} 23 inline void build(int &x,int l,int r){ 24 if (!x) x=(++cnt);if (l==r) return; 25 build(L[x],l,mid);build(R[x],mid+1,r); 26 } 27 inline void update(int &x,int l,int r,int p,ll v){ 28 L[++cnt]=L[x];R[cnt]=R[x];sum[cnt]=sum[x];cst[cnt]=cst[x];x=cnt; 29 sum[x]+=v;cst[x]+=1ll*p*v;if (l==r) return; 30 if (p<=mid) update(L[x],l,mid,p,v); 31 else update(R[x],mid+1,r,p,v); 32 } 33 inline ll query(int x,int l,int r,ll v){ 34 if (l==r) return l*v; 35 if (v<=sum[L[x]]) return query(L[x],l,mid,v); 36 return cst[L[x]]+query(R[x],mid+1,r,v-sum[L[x]]); 37 } 38 int main() 39 { 40 n=in();m=in(); 41 for (int i=1;i<=n;++i){ 42 a[i].d=in();a[i].p=in(); 43 a[i].l=in();mx=max(mx,a[i].p); 44 }sort(a+1,a+n+1,cmp);build(rt[0],1,mx); 45 for (int i=1;i<=n;++i) rt[i]=rt[i-1],update(rt[i],1,mx,a[i].p,a[i].l); 46 for (int i=1;i<=m;++i){ 47 g=in();k=in(); 48 int l=1,r=n,res=-1; 49 while (l<=r){ 50 if (k<=sum[rt[mid]]&&query(rt[mid],1,mx,k)<=g) res=mid,r=mid-1; 51 else l=mid+1; 52 }printf("%d\n",(res<0?res:a[res].d)); 53 }return 0; 54 }
BZOJ 1076/Luogu P2473 [SCOI2008]奖励关
期望dp.令f[i][s]表示f在前i-1轮已处理状态为s,后n-i+1轮到达此状态的期望。
枚举下一轮选择的宝物j,若j可选,则分为选择或不选择,选取较大值,否则则只能不选择。
转移方程见程序。答案即为f[1][0]的值。
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define MK 103 5 #define MN 20 6 #define MM (1<<15) 7 using namespace std; 8 inline int in(){ 9 int x=0;bool f=0; char c; 10 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 11 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 12 return f?-x:x; 13 } 14 double f[MK][MM]; 15 int p[MN],v[MN],k,n,x; 16 int main() 17 { 18 k=in();n=in(); 19 for (int i=0;i<n;++i){ 20 v[i]=in();x=in()-1; 21 while (x>=0) p[i]+=(1<<x),x=in()-1; 22 } 23 for (int i=k;i;--i) 24 for (int s=0;s<(1<<n);++s){ 25 for (int j=0;j<n;++j) 26 if ((p[j]&s)==p[j]) 27 f[i][s]+=max(f[i+1][s],f[i+1][s|(1<<j)]+v[j]); 28 else f[i][s]+=f[i+1][s];f[i][s]/=n; 29 }printf("%.6lf",f[1][0]);return 0; 30 }
BZOJ 3668/LuoguP2114 [NOI2014]起床困难综合症
分别求出每一位是0/1的情况经过所有运算后的结果,这可以用二进制位全0/全1的数分别模拟。
在取值范围内从高位向低位贪心选取,若两种操作结果相同,则选取二进制位较小的数(即0)。否则选取使该位结果为1的数。
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 inline int in(){ 6 int x=0;bool f=0; char c; 7 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 8 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 9 return f?-x:x; 10 } 11 int n,m,x,mx,bt,b0,b1,res; 12 char ch; 13 int main() 14 { 15 n=in();m=in();b0=0;b1=-1; 16 for (int i=1;i<=n;++i){ 17 ch=getchar();while (ch!='A'&&ch!='O'&&ch!='X') ch=getchar(); 18 x=in();mx=max(mx,x); 19 if (ch=='A') b0&=x,b1&=x; 20 else if (ch=='O') b0|=x,b1|=x; 21 else b0^=x,b1^=x; 22 } 23 for (;mx;mx>>=1,++bt); 24 for (int i=bt-1;i>=0;--i){ 25 if ((b0>>i)&1) res+=(1<<i); 26 else if ((b1&(1<<i))<=m&&((b1>>i)&1)) res+=(1<<i),m-=(1<<i); 27 }printf("%d",res);return 0; 28 }
BZOJ1086/Luogu P2325 [SCOI2005]王室联邦
https://www.cnblogs.com/FallDream/p/bzoj1086.html
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define MN 1005 5 using namespace std; 6 inline int in(){ 7 int x=0;bool f=0; char c; 8 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 9 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 10 return f?-x:x; 11 } 12 struct edge{ 13 int to,nxt; 14 }e[MN<<1]; 15 int h[MN],bt[MN],res[MN],cpt[MN],st[MN]; 16 int n,b,x,y,ct,cnt,top=0; 17 bool vis[MN]; 18 inline void ins(int x,int y){ 19 e[++cnt].to=y;e[cnt].nxt=h[x];h[x]=cnt; 20 } 21 inline void dfs(int u){ 22 for (int i=h[u];i;i=e[i].nxt){ 23 int v=e[i].to; 24 if (vis[v]) continue; 25 vis[v]=1;bt[v]=top;dfs(v); 26 if (top-bt[u]>=b){ 27 cpt[++ct]=u; 28 while (top>bt[u]) res[st[top]]=ct,--top; 29 } 30 }st[++top]=u; 31 } 32 int main() 33 { 34 n=in();b=in();if (n<b) {printf("0");return 0;} 35 for (int i=1;i<n;++i) { 36 x=in();y=in();ins(x,y);ins(y,x); 37 }bt[1]=0;dfs(1); 38 while (top) res[st[top]]=ct,--top;printf("%d\n",ct); 39 for (int i=1;i<=n;++i) printf("%d ",res[i]);puts(""); 40 for (int i=1;i<=ct;++i) printf("%d ",cpt[i]); 41 return 0; 42 }
BZOJ 1053/Luogu P1463 [HAOI2007]反素数
将一个数n质因数分解,使n=∏pici(pi<pi+1,ci≠0),则ci≥ci+1.
可以发现前12个质数之积大于2×109,故对前12个质数打表,dfs+剪枝求出不超过n的x,使得g(x)在1~n内最大即可。
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ll long long 5 #define MX 12 6 using namespace std; 7 inline ll in(){ 8 ll x=0;bool f=0;char c; 9 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 10 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 11 return f?-x:x; 12 } 13 const int pri[MX+1]={0,2,3,5,7,11,13,17,19,23,29,31}; 14 ll n,mx,mp; 15 inline void dfs(int step,ll sum,int num,int fct){ 16 if (step==MX){ 17 if (num>mx||(num==mx&&sum<mp)) {mx=num;mp=sum;} return; 18 }ll prd=1; 19 for (int i=0;i<=fct;++i){ 20 dfs(step+1,sum*prd,num+(num*i),i); 21 prd*=pri[step];if (sum*prd>n) return; 22 } 23 } 24 int main() 25 { 26 n=in();dfs(1,1,1,31); 27 printf("%d",mp);return 0; 28 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步