• 洛谷 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 }
  • 相关阅读:
    百度面试题:把数组排成最小的数
    面试题:在O(1)时间删除链表结点
    从第一字符串中删除第二个字符串中所有的字符
    在一个字符串中找到第一个只出现一次的字符
    大整数运算
    输出1到最大的N位数
    删除字符串中的数字并压缩字符串
    排列 或组合问题的解法(包含回溯法)
    卡特兰数(Catalan)简介
    编程之美-分层遍历二叉树
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9260738.html
Copyright © 2020-2023  润新知