题解:AT_abc420_f [ABC420F] kirinuki
Unnamed114514 · · 题解
先预处理出每个位置可以向上延长几个,记作
注意到
时间复杂度
::::info[code]
#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f3f3f3f3fLL
#define double long double
#define eps 1e-8
#define endl '\n'
using namespace std;
const int N=5e5+5;
int n,m,k,ans,res,f[N],cnt[N];
vector<int> a[N],l[N],r[N];
vector<char> c[N];
vector<bool> b[N];
vector<pair<int,int> > v[N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m>>k;
if(n>m){
for(int i=1;i<=n;++i) a[i].resize(m+1),b[i].resize(m+1),c[i].resize(m+1),l[i].resize(m+1),r[i].resize(m+1);
for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) cin>>c[i][j];
} else{
for(int i=1;i<=m;++i) a[i].resize(n+1),b[i].resize(n+1),c[i].resize(n+1),l[i].resize(n+1),r[i].resize(n+1);
for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) cin>>c[j][i];
swap(n,m);
}
for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){
if(c[i][j]=='#') a[i][j]=0;
else{
a[i][j]=1;
if(i>1) a[i][j]+=a[i-1][j];
}
v[a[i][j]].emplace_back(make_pair(i,j));
}
for(int i=n;i;--i){
if(i==n||k/i!=k/(i+1)){
for(int j=1;j<=m;++j)
if(j<=k/i) f[j]=j*(j+1)/2;
else f[j]=j*(k/i)-(k/i)*(k/i+1)/2+(k/i);
res=0;
for(int j=1;j<=m;++j) res+=cnt[j]*f[j];
}
for(auto p:v[i]){
int x=p.first,y=p.second;
if((y>1&&b[x][y-1])&&(y<m&&b[x][y+1])){
res-=f[(y-1)-l[x][y-1]+1]+f[r[x][y+1]-(y+1)+1],--cnt[(y-1)-l[x][y-1]+1],--cnt[r[x][y+1]-(y+1)+1];
r[x][l[x][y-1]]=r[x][y+1],l[x][r[x][y+1]]=l[x][y-1];
res+=f[r[x][y+1]-l[x][y-1]+1],++cnt[r[x][y+1]-l[x][y-1]+1];
} else if(y>1&&b[x][y-1]){
res-=f[(y-1)-l[x][y-1]+1],--cnt[(y-1)-l[x][y-1]+1];
r[x][l[x][y-1]]=y,l[x][y]=l[x][y-1];
res+=f[y-l[x][y-1]+1],++cnt[y-l[x][y-1]+1];
} else if(y<m&&b[x][y+1]){
res-=f[r[x][y+1]-(y+1)+1],--cnt[r[x][y+1]-(y+1)+1];
l[x][r[x][y+1]]=y,r[x][y]=r[x][y+1];
res+=f[r[x][y+1]-y+1],++cnt[r[x][y+1]-y+1];
} else{
res+=f[1],++cnt[1];
l[x][y]=r[x][y]=y;
}
b[x][y]=1;
}
ans+=res;
}
cout<<ans<<endl;
return 0;
}
::::