正题
题目链接:https://gmoj.net/senior/#contest/show/3146/2
题目大意
一个以左上角为端点的子矩形价值定义为区间内唯一的数的数量,求所有子矩形的权值和。
解题思路
考虑每个数字的贡献,对于相同的数字,产生贡献的右下角一定是一个若干个矩形。我们对于每个数存一个hi,li,rih_i,l_i,r_ihi,li,ri表示上一个有贡献的点的xxx坐标,在li∼ril_i\sim r_ili∼ri范围可以产生贡献。
然后统计即可,时间复杂度O(nm)O(nm)O(nm)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1110,XJQ=19900907;
ll n,m,h[N*N],r[N*N],l[N*N],ans;
int main()
{scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++){for(ll j=1;j<=m;j++){ll x;scanf("%lld",&x);if(!h[x]){h[x]=i;l[x]=j;r[x]=m+1;}else if(j<l[x]){(ans+=(i-h[x])*(r[x]-l[x])%XJQ)%=XJQ;h[x]=i;r[x]=l[x];l[x]=j;}else if(j<r[x]){(ans+=(i-h[x])*(r[x]-j)%XJQ)%=XJQ;r[x]=j;}}}for(ll i=1;i<=n*m;i++)if(h[i])(ans+=(n-h[i]+1)*(r[i]-l[i])%XJQ)%=XJQ;printf("%lld",ans);
}