2018ICPC南京赛区网络选拔B The writing on the wall (单调栈)
题目链接:
https://nanti.jisuanke.com/t/30991
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
#define push_back pb;
vector<int>Q[maxn];
pair<int,int>P[maxn];
int h[maxn];
int main()
{
int n,m,T,i,j,k,s;
long long ans;
int x,y;
scanf("%d",&T);
for(s=1;s<=T;s++)
{
ans=0;
scanf("%d%d%d",&m,&n,&k);
for(i=1;i<=k;i++)
{
scanf("%d%d",&P[i].second,&P[i].first);
}
sort(P+1,P+1+k);
int temp=1;
memset(h,0,sizeof(h));
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(temp<=k&&P[temp].first==i&&P[temp].second==j)
{
// cout<<"-------------"<<endl;
temp++;
h[j]=0;
}
else h[j]++;
}
int top=0;
int sta[maxn];
h[0]=0;
sta[++top]=0;
long long subans=0;
for(j=1;j<=m;j++)
{
while(top>0&&h[j]<=h[sta[top]])
{
subans-=1ll*h[sta[top]]*(sta[top]-sta[top-1]);
top--;
}
sta[++top]=j;
subans+=1ll*h[sta[top]]*(sta[top]-sta[top-1]);
ans+=subans;
}
}
printf("Case #%d: %lld\n",s,ans);
}
}
Q.E.D.