洛谷 P3400 仓鼠窝

卡常

 1 #pragma GCC optimize(2)
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 using namespace std;
 7 typedef long long LL;
 8 #define fi first
 9 #define se second
10 #define mp make_pair
11 #define pb push_back
12 typedef pair<int,int> pi;
13 int n,m,a[3010][3010];
14 int xx[3010][3010];
15 int t1[3010],lst[3010],r;
16 int ta,sz[3010];LL ans;
17 int f1[3010],dd[3010],nxt[3010],mem,sz1[3010];
18 inline void read(int &x)
19 {
20     x=0; int f=1; char ch=getchar();
21     while( (ch<'0' || ch>'9') && ch!='-') ch=getchar(); if(ch=='-') {f=-1; ch=getchar();}
22     while(ch>='0' && ch <='9') x=x*10+ch-'0',ch=getchar();
23     x*=f;
24 }
25 int main()
26 {
27     int i,j,k,t,p;
28     scanf("%d%d",&n,&m);
29     for(i=1;i<=n;i++)
30         for(j=1;j<=m;j++)
31         {
32             read(a[i][j]);
33             a[i][j]^=1;
34             if(a[i][j]==1)
35             {
36                 for(k=i;k>=1;k--)
37                 {
38                     if(xx[k][j])    break;
39                     xx[k][j]=i;
40                 }
41             }
42         }
43     for(i=1;i<=n;i++)
44         for(j=1;j<=m;j++)
45         {
46             if(xx[i][j]==0)
47                 xx[i][j]=n+1;
48             xx[i][j]-=i;
49         }
50 //    for(i=1;i<=n;i++)
51 //    {
52 //        for(j=1;j<=m;j++)
53 //            printf("%lld ",xx[i][j]);
54 //        puts("");
55 //    }
56 //    return 0;
57     for(i=1;i<=n;i++)
58     {
59         r=0;
60         for(j=m;j>=1;j--)
61         {
62             while(r&&xx[i][t1[r]]>xx[i][j])    lst[t1[r]]=j,r--;
63             t1[++r]=j;
64         }
65         while(r)    lst[t1[r]]=0,r--;
66         mem=0;
67         for(j=1;j<=m;j++)    sz1[j]=0,f1[j]=0;
68         for(j=1;j<=m;j++)
69             if(lst[j]!=0)
70                 dd[++mem]=j,nxt[mem]=f1[lst[j]],f1[lst[j]]=mem,sz1[lst[j]]++;
71         for(j=1;j<=m;j++)    sz[j]=0;
72         for(j=m;j>=1;j--)    sz[j]+=sz1[j],sz[lst[j]]+=sz[j];
73         //for(j=1;j<=m;j++)    printf("%lld ",lst[j]);
74         //puts("");
75         ta=0;t=0x3f3f3f3f;
76         for(j=1;j<=m;j++)    t=min(t,xx[i][j]),ta+=t;
77         for(j=1;j<=m;j++)
78         {
79             ans+=ta;
80             for(k=f1[j];k;k=nxt[k])
81             {
82                 p=dd[k];
83                 ta+=(sz[p]+1)*(xx[i][p]-xx[i][lst[p]]);
84             }
85             ta-=xx[i][j];
86         }
87     }
88     printf("%lld",ans);
89     return 0;
90 }

猜你喜欢

转载自www.cnblogs.com/hehe54321/p/9260738.html