【洛谷】题解 P3400 【仓鼠窝】

此题有坑!!! 注意要开long long和常数优化。

大家可以看前几位大佬的思路,我也跟他们差不多

希望大家可以用我的博客看,那样更好传送门

第一次提交时卡无限Juding了 https://www.luogu.org/record/show?rid=14907781

// luogu-judger-enable-o2
//#define LOCAL
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <bits/stdc++.h>

#define INF 0×7f
#define ull unsigned long long
#define FOR(a, b, n) for(int a = b; b >= n ? a >= n : a <= n; b >= n ? a-- : a++)
#define M(a, n) memset(a, n, sizeof(a));
#define S(n) scanf("%d", &n)
#define P(n) printf("%lld", n)
#define G(n) getline(cin, n)
#define PI acos(-1.0)
#define fi first
#define se second

using namespace std;

const int NR = 3005;

using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
inline void read(int &x)
{
    x = 0; 
    char ch = getchar();
    while(ch < '0' || ch > '9') 
    	ch = getchar();
    while(ch >= '0' && ch <= '9')
   	{
   		x = (x << 1) + (x << 3) + (ch ^ 48);
   		ch = getchar();
   	}
}
int n, m, top; 
ll cnt, ans;
int A[NR][NR], pre[NR][NR], H[NR];
pa sta[NR];    
int main() {
	#ifdef LOCAL
		freopen(".in", "r", stdin);
		freopen(".out", "w", stdout);
	#endif
    read(n);
    read(m);
    FOR(i, 1, n) 
    	FOR(j, 1, m) 
    		read(A[i][j]);
    FOR(i, 1, n) {
        cnt = 0;
        top = 0; 
        pa tmp;
        FOR(j, 1, m) {
            if(!A[i][j])
            {
            	H[j] = 0; 
            	cnt = 0;
            	top = 0;
            	continue;
            }
            tmp.fi = ++H[j]; 
            tmp.se = 1;
            while(top && sta[top].fi >= tmp.fi) {
                tmp.se = tmp.se + sta[top].se;
                cnt -= 1ll * sta[top].fi * sta[top].se;
                top--;
            }
            sta[++top] = tmp;
            cnt += 1ll * tmp.fi * tmp.se;
            ans += cnt;
        }
    }
    P(ans);
    //cout<<"AC";
    return 0;
}
//Jiang_zi_chuan原创
//小号Jzc2008
//本人是个十足的蒟蒻没事不要@(有事请发到邮箱[email protected])

猜你喜欢

转载自blog.csdn.net/jzc20080511/article/details/85923107