HZOI20190816模拟23 mine/water/gcd
Posted juve
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HZOI20190816模拟23 mine/water/gcd相关的知识,希望对你有一定的参考价值。
A:mine
只是一个简单的dp。。。。是博主太蒻了。。。
设f[i][j],表示到第i位,状态是j的方案数,其中$j\in[0,5]$
j==0表示填0,j==1表示填1,且i-1位是雷;
j==2表示填2,j==3表示填雷,j==5表示填1,且i-1位不是雷
思考一下,得到方程:
$f[i][4]=f[i-1][3]$
$f[i][1]=f[i-1][4]+f[i-1][0]$
$f[i][3]=f[i-1][1]+f[i-1][2]+f[i-1][3]$
$f[i][0]=f[i-1][4]+f[i-1][0]$
$f[i][2]=f[i-1][3]$
然后就没什么了
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #define int long long using namespace std; const int MAXN=1e6+1; const int mod=1e9+7; int len,ans=0,f[2][5]; char s[MAXN]; signed main() scanf("%s",s+1); len=strlen(s+1); if(s[1]==‘*‘) f[1][3]=1; else if(s[1]==‘1‘) f[1][1]=1; else if(s[1]==‘0‘) f[1][0]=1; else if(s[1]==‘?‘) f[1][3]=f[1][1]=f[1][0]=1; for(int i=2;i<=len;i++) f[i&1][0]=f[i&1][1]=f[i&1][2]=f[i&1][3]=f[i&1][4]=0; if(s[i]==‘?‘) f[i&1][4]=f[i&1^1][3]%mod; f[i&1][1]=(f[i&1^1][4]+f[i&1^1][0])%mod; f[i&1][3]=((f[i&1^1][1]+f[i&1^1][2])%mod+f[i&1^1][3])%mod; f[i&1][0]=(f[i&1^1][4]+f[i&1^1][0])%mod; f[i&1][2]=f[i&1^1][3]%mod; else if(s[i]==‘1‘) f[i&1][4]=f[i&1^1][3]%mod; f[i&1][1]=(f[i&1^1][4]+f[i&1^1][0])%mod; else if(s[i]==‘*‘) f[i&1][3]=((f[i&1^1][1]+f[i&1^1][2])%mod+f[i&1^1][3])%mod; else if(s[i]==‘0‘) f[i&1][0]=(f[i&1^1][4]+f[i&1^1][0])%mod; else f[i&1][2]=f[i&1^1][3]%mod; ans=((f[len&1][4]+f[len&1][0])%mod+f[len&1][3])%mod; printf("%lld\n",ans); return 0;
B:water
一个块的高度就是从这个块走出矩形的所有路径上的最大值的最小值。
相邻块连边,权值为两块的较大值,矩形边界的块向“矩形外”连边,权值为 max(高度,0),
做最小生成树,然后每个点的积水高度就是这个点到根节点路径上的最大边权减去这个点的点权
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 305 #define inf 0x7fffffff using namespace std; int n,m,a[MAXN][MAXN],dep[MAXN*MAXN]; int calc(int i,int j) return (i-1)*m+j; struct node int fr,to,w,nxt; friend bool operator < (node a,node b) return a.w<b.w; e[MAXN*MAXN*4],edge[MAXN*MAXN*4]; int pre[MAXN*MAXN],cnt=0,tot=0; void add(int u,int v,int w) cnt++; e[cnt].to=v,e[cnt].fr=u; e[cnt].w=w; void ADD(int u,int v,int w) tot++; edge[tot].to=v,edge[tot].fr=u; edge[tot].nxt=pre[u],pre[u]=tot; edge[tot].w=w; int fa[MAXN*MAXN]; int find(int x) return fa[x]==x?x:fa[x]=find(fa[x]); void kruskal() for(int i=1;i<=n*m+1;i++) fa[i]=i; sort(e+1,e+cnt+1); int sum_edge=0,sum=0; for(int i=1;i<=cnt;i++) int x=find(e[i].fr),y=find(e[i].to); if(x!=y) fa[x]=y; ADD(x,y,e[i].w); ADD(y,x,e[i].w); sum_edge++; if(sum_edge==n*m) break; bool vis[MAXN*MAXN]; void dfs(int x,int fa) vis[x]=1; for(int i=pre[x];i;i=edge[i].nxt) int y=edge[i].to; if(y==fa) continue; if(vis[y]) continue; dep[y]=max(dep[x],max(dep[y],edge[i].w)); dfs(y,x); int main() scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(j+1<=m) add(calc(i,j),calc(i,j+1),max(a[i][j],a[i][j+1])); add(calc(i,j+1),calc(i,j),max(a[i][j],a[i][j+1])); if(i+1<=n) add(calc(i,j),calc(i+1,j),max(a[i][j],a[i+1][j])); add(calc(i+1,j),calc(i,j),max(a[i][j],a[i+1][j])); for(int i=1;i<=m;i++) add(n*m+1,calc(1,i),max(0,a[1][i])); add(calc(1,i),n*m+1,max(0,a[1][i])); add(n*m+1,calc(n,i),max(0,a[n][i])); add(calc(n,i),n*m+1,max(0,a[n][i])); for(int i=2;i<n;i++) add(n*m+1,calc(i,1),max(0,a[i][1])); add(calc(i,1),n*m+1,max(0,a[i][1])); add(n*m+1,calc(i,m),max(0,a[i][m])); add(calc(i,m),n*m+1,max(0,a[i][m])); kruskal(); memset(dep,-0x7f,sizeof(dep)); dfs(n*m+1,0); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) printf("%d ",dep[calc(i,j)]-a[i][j]); puts(""); return 0;
C:gcd
并不是gcd,好像有mobius反演的内容,博主先咕了
以上是关于HZOI20190816模拟23 mine/water/gcd的主要内容,如果未能解决你的问题,请参考以下文章