• 微信公众号：美女很有趣。 工作之余，放松一下，关注即送10G+美女照片！

# 题解 万猪拱塔

5小时前 4次浏览

(f(l)=max(l, r)-min(l,r)+l=r)

(f(l) geqslant 4, f(r)=4) 所以和上面一样统计答案

Code:

``````#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 200010
#define ll long long
#define reg register int
#define fir first
#define sec second
#define make make_pair
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}

int n, m;
int **mat, **w;
pair<int, int> rk[N];
const ll mod=998244353;
inline void md(ll& a, ll b) {a+=b; a=a>=mod?a-mod:a;}

namespace force{
ll ans;
void solve() {
for (reg i=1; i<=n; ++i) {
for (reg j=1; j<=m; ++j) {
for (reg k=i; k<=n; ++k) {
for (reg h=j; h<=m; ++h) {
int maxn=0, minn=INF;
for (reg x=i; x<=k; ++x) {
for (reg y=j; y<=h; ++y) {
maxn=max(maxn, w[x][y]);
minn=min(minn, w[x][y]);
}
}
if (maxn-minn == (k-i+1)*(h-j+1)-1)
ans = (ans+(k-i+1)*(h-j+1)%mod)%mod;
}
}
}
}
printf("%lldn", ans);
exit(0);
}
}

ll ans;
int tem1[N], tem2[N];
#define max(a, b) ((a)>(b)?(a):(b))
#define min(a, b) ((a)<(b)?(a):(b))
void check(int len) {
//cout<<"check: "<<len<<endl;
for (reg i=m,maxn,minn; i; --i) {
maxn=tem1[i], minn=tem2[i];
for (reg j=i; j; --j) {
maxn=max(maxn, tem1[j]);
minn=min(minn, tem2[j]);
if (maxn-minn == len*(i-j+1)-1)
md(ans, len*(i-j+1)%mod); //, cout<<"md: "<<len*(j-i+1)<<endl;
}
}
}
void solve() {
for (reg i=1; i<=n; ++i) {
for (reg j=i; j<=n; ++j) {
for (reg k=1; k<=m; ++k) tem1[k]=0, tem2[k]=INF;
for (reg k=i; k<=j; ++k)
for (reg h=1; h<=m; ++h) {
tem1[h]=max(tem1[h], w[k][h]);
tem2[h]=min(tem2[h], w[k][h]);
}
check(j-i+1);
//cout<<"ij: "<<i<<' '<<j<<' '<<ans<<endl;
}
}
printf("%lldn", ans);
exit(0);
}
#undef max
#undef min
}

ll ans;
#define max(a, b) ((a)>(b)?(a):(b))
#define min(a, b) ((a)<(b)?(a):(b))
struct que1{
int l=1, r=0;
struct node{int val, pos; inline void build(int v, int p) {val=v; pos=p;}}; node* q;
inline void set(int k) {l=1, r=0; q=new node[k];}
inline void clear() {l=1; r=0;}
inline void add(int val, int pos) {
while (l<=r && q[r].val<=val) --r;
q[++r].build(val, pos);
}
inline int query() {return q[l].val;}
inline void upd(int deline) {
while (l<=r && q[l].pos<deline) ++l;
}
}tem1[N];
struct que2{
int l=1, r=0;
struct node{int val, pos; inline void build(int v, int p) {val=v; pos=p;}}; node* q;
inline void set(int k) {l=1, r=0; q=new node[k];}
inline void clear() {l=1; r=0;}
inline void add(int val, int pos) {
while (l<=r && q[r].val>=val) --r;
q[++r].build(val, pos);
}
inline int query() {return q[l].val;}
inline void upd(int deline) {
while (l<=r && q[l].pos<deline) ++l;
}
}tem2[N];
void check(int len) {
//cout<<"check: "<<len<<endl;
for (reg i=m,maxn,minn; i; --i) {
maxn=tem1[i].query(), minn=tem2[i].query();
for (reg j=i; j; --j) {
maxn=max(maxn, tem1[j].query());
minn=min(minn, tem2[j].query());
if (maxn-minn == len*(i-j+1)-1)
md(ans, len*(i-j+1)%mod); //, cout<<"md: "<<len*(j-i+1)<<endl;
}
}
}
void solve() {
for (reg i=1; i<=m; ++i) tem1[i].set(n+10), tem2[i].set(n+10);
for (reg len=1; len<=n; ++len) {
for (reg i=1; i<=m; ++i) tem1[i].clear(), tem2[i].clear();
for (reg i=1; i<=len; ++i)
for (reg j=1; j<=m; ++j)
for (reg i=len; i<=n; ++i) {
for (reg j=1; j<=m; ++j) tem1[j].upd(i-len+1), tem2[j].upd(i-len+1);
check(len);
if (i<n) {
for (reg j=1; j<=m; ++j) tem1[j].add(w[i+1][j], i+1), tem2[j].add(w[i+1][j], i+1);
}
}
}
printf("%lldn", ans);
exit(0);
}
#undef max
#undef min
}

ll mins[N<<2], ans;
int tl[N<<2], tr[N<<2], minf[N<<2], minc[N<<2], tag[N<<2];
#define tl(p) tl[p]
#define tr(p) tr[p]
#define minf(p) minf[p]
#define minc(p) minc[p]
#define mins(p) mins[p]
#define tag(p) tag[p]
inline int max(int a, int b) {return a>b?a:b;}
inline int min(int a, int b) {return a<b?a:b;}
void pushup(int p) {
minf(p)=min(minf(p<<1), minf(p<<1|1)); minc(p)=mins(p)=0;
if (minf(p<<1)==minf(p)) {
minc(p)+=minc(p<<1);
md(mins(p), mins(p<<1));
}
if (minf(p<<1|1)==minf(p)) {
minc(p)+=minc(p<<1|1);
md(mins(p), mins(p<<1|1));
}
}
void spread(int p) {
minf(p<<1)+=tag(p); tag(p<<1)+=tag(p);
minf(p<<1|1)+=tag(p); tag(p<<1|1)+=tag(p);
tag(p)=0;
}
void build(int p, int l, int r) {
tl(p)=l; tr(p)=r; minf(p)=INF;
if (l==r) {minf(p)=INF; minc(p)=1; mins(p)=l-1; return ;}
int mid=(l+r)>>1;
build(p<<1, l, mid);
build(p<<1|1, mid+1, r);
}
void upd(int p, int pos, int dat) {
if (tl(p)==tr(p)) {minf(p)=dat; return ;}
int mid=(tl(p)+tr(p))>>1;
if (pos<=mid) upd(p<<1, pos, dat);
else upd(p<<1|1, pos, dat);
pushup(p);
}
void upd(int p, int l, int r, int dat) {
if (l<=tl(p) && r>=tr(p)) {minf(p)+=dat; tag(p)+=dat; return ;}
int mid=(tl(p)+tr(p))>>1;
if (l<=mid) upd(p<<1, l, r, dat);
if (r>mid) upd(p<<1|1, l, r, dat);
pushup(p);
}
void query(int p) {
if (tl(p)==tr(p)) {printf("%d ", minf(p)); return ;}
query(p<<1); query(p<<1|1);
if (p==1) printf("n");
}
void calc(int r, int x1, int x2, int x3) {
//if (r==4) cout<<"calc: "<<r<<' '<<x1<<' '<<x2<<' '<<x3<<endl;
int t[5]={0, r, x1, x2, x3};
sort(t, t+5);
//if (r==4) {cout<<"t: "; for (int i=0; i<4; ++i) cout<<t[i]<<' '; cout<<endl;}
if (t[1]==r) {if (r>1) upd(1, 1, r-1, 1); return ;}
int pos=1, base=1;
while (t[pos]!=r) ++pos; --pos;
//cout<<"pos: "<<pos<<endl;
for (; pos; ++base,--pos) {
if (base==1) {
upd(1, t[pos-1]+1, t[pos], -1); //, cout<<"go cge: "<<t[pos-1]+1<<' '<<t[pos]<<' '<<-1<<endl;
if (t[pos]+1<=t[pos+1]-1) upd(1, t[pos]+1, t[pos+1]-1, 1);
}
else if (base==2) upd(1, t[pos-1]+1, t[pos], 1); //, cout<<"go cge: "<<t[pos-1]+1<<' '<<t[pos]<<' '<<1<<endl;
else if (base==3) upd(1, t[pos-1]+1, t[pos], -1); //, cout<<"go cge: "<<t[pos-1]+1<<' '<<t[pos]<<' '<<-1<<endl;
else puts("error");
}
//if (r==4) cout<<endl;
}
void solve() {
//memset(minf, 127, sizeof(minf));
build(1, 1, n*m);
for (reg i=1,x,y; i<=n*m; ++i) {
//cout<<"i: "<<i<<endl;
upd(1, i, 4);
//query(1);
x=rk[i].fir, y=rk[i].sec;
calc(i, w[x-1][y], w[x][y-1], w[x-1][y-1]);
calc(i, w[x-1][y], w[x][y+1], w[x-1][y+1]);
calc(i, w[x+1][y], w[x][y-1], w[x+1][y-1]);
calc(i, w[x+1][y], w[x][y+1], w[x+1][y+1]);
///query(1);
//cout<<"minf: "<<minf(1)<<endl;
if (minf(1)==4) {
ans=(ans+1ll*i*minc(1)-mins(1))%mod;
//cout<<"ans: "<<ans<<endl;
//cout<<"minc: "<<minc(1)<<endl;
//cout<<"mins: "<<mins(1)<<endl;
}
else ans=(ans+1)%mod;
//cout<<endl;
}
printf("%lldn", ans);
exit(0);
}
}

signed main()
{
freopen("pig.in", "r", stdin);
freopen("pig.out", "w", stdout);

if (n<=m) {
w=new int*[n+5];
for (reg i=0; i<=n+1; ++i) {w[i]=new int[m+5]; memset(w[i], 127, sizeof(int)*(m+5));}
for (reg i=1; i<=n; ++i) for (reg j=1; j<=m; ++j) {w[i][j]=read(); rk[w[i][j]]=make(i, j);}
}
else {
mat=new int*[n+5]; w=new int*[m+5];
for (reg i=0; i<=n+1; ++i) mat[i]=new int[m+5];
for (reg i=1; i<=n; ++i) for (reg j=1; j<=m; ++j) mat[i][j]=read();
for (reg i=0; i<=m+1; ++i) {w[i]=new int[n+5]; memset(w[i], 127, sizeof(int)*(n+5));}
for (reg i=1; i<=m; ++i) for (reg j=1; j<=n; ++j) {w[i][j]=mat[j][i]; rk[w[i][j]]=make(i, j);}
swap(n, m);
}