Description
在地面上有一个水箱,它的俯视图被划分成了n行m列个方格,相邻两个方格之间有一堵厚度可以忽略不计的墙,水
箱与外界之间有一堵高度无穷大的墙,因此水不可能漏到外面。已知水箱内每个格子的高度都是[0,H]之间的整数
,请统计有多少可能的水位情况。因为答案可能很大,请对10^9+7取模输出。两个情况不同当且仅当存在至少一个
方格的水位在两个情况中不同。
Input
第一行包含三个正整数n,m,H(n*m<=500000,1<=H<=10^9)。
接下来n行,每行m-1个整数a[i][j](1<=a[i][j]<=H),表示(i,j)和(i,j+1)之间的墙的高度。
接下来n-1行,每行m个整数b[i][j](1<=b[i][j]<=H),表示(i,j)和(i+1,j)之间的墙的高度。
Output
输出一行一个整数,即方案数模10^9+7的结果。
格子作为点,墙作为边,kruskal求最小生成树,维护每个连通块的水位不溢出的方案数
#include<bits/stdc++.h> typedef long long i64; const int N=5e5+77,P=1e9+7; char ib[N*25],*ip=ib; int _(){int x;scanf("%d",&x);return x;} int n,m,h,ep=0; struct edge{ int a,b,c; }e[N*2],eb[N*2]; struct node{ int f,sz,mx,s; int operator[](int c){return c-mx+s;} }f[N]; void rsort(edge*a,edge*b,int n){ for(int d=0;d<30;d+=10){ edge*p=b,*rs[1111]; int ts[1111]; memset(ts,0,sizeof(ts)); for(int i=0;i<n;++i)++ts[a[i].c>>d&1023]; for(int i=0;i<1024;++i)rs[i]=p,p+=ts[i]; for(int i=0;i<n;++i)*rs[a[i].c>>d&1023]++=a[i]; std::swap(a,b); } } int gf(int x){ while(x!=f[x].f)x=f[x].f=f[f[x].f].f; return x; } int main(){ n=_(),m=_(),h=_(); for(int i=1;i<=n;++i){ for(int j=1,x=(i-1)*m;j<m;++j)e[ep++]=(edge){x+j,x+j+1,_()}; } for(int i=1;i<n;++i){ for(int j=1,x=(i-1)*m;j<=m;++j)e[ep++]=(edge){x+j,x+j+m,_()}; } rsort(e,eb,ep); for(int i=1;i<=n*m;++i)f[i]=(node){i,1,-1,0}; for(int i=0;i<ep;++i){ int a=gf(eb[i].a),b=gf(eb[i].b),c=eb[i].c; if(a==b)continue; if(f[a].sz<f[b].sz)std::swap(a,b); f[b].f=a; f[a].s=(i64)f[a][c]*f[b][c]%P; f[a].mx=c; f[a].sz+=f[b].sz; } printf("%d\n",f[gf(1)][h]%P); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
· 终于决定:把自己家的能源管理系统开源了!
· C#实现 Winform 程序在系统托盘显示图标 & 开机自启动
· 了解 ASP.NET Core 中的中间件
· 实现windows下简单的自动化窗口管理
· 【C语言学习】——命令行编译运行 C 语言程序的完整流程