zoukankan      html  css  js  c++  java
  • 【分块】【链表】bzoj2738 矩阵乘法

    http://www.cnblogs.com/jianglangcaijin/p/3460012.html

    首先将矩阵的数字排序。设置size,每次将size个数字插入。插入时,我们用h[i][j]记录该位置的数字是否已经插入;用sum[i][j]表示子矩阵(1,1)到(i,j)已经插入的数字个数总和。每次插入后,暴力扫一次询问,若查询子矩阵的数字个数大于等于K则答案就在此次插入的数字中;然后将该询问从链表中删除。

    怎样知道是插入的哪个数字呢?暴力O(sqrt(n))地扫描当前这段区间,依次判断这个数插入时是否恰好达到k个。

    复杂度真心不知道怎么分析了……跪了……

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<list>
     5 using namespace std;
     6 struct Ask{int x1,y1,x2,y2,k,p;
     7 Ask(const int &x){scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&k); p=x;}Ask(){}};
     8 list<Ask>Q;
     9 typedef list<Ask>::iterator ITER;
    10 struct Val3{int v,x,y;}Ins[250001];
    11 bool operator < (const Val3 &a,const Val3 &b){return a.v<b.v;}
    12 int n,m,sumv[501][501],q,anss[60001];
    13 bool vis[501][501];
    14 void makeblock()
    15 {
    16     int sz=sqrt(q),sum=1; if(!sz) sz=1; 
    17     for(;sum*sz<q;++sum)
    18       {
    19           int l=(sum-1)*sz+1; int r=sum*sz;
    20           for(int i=l;i<=r;++i) vis[Ins[i].x][Ins[i].y]=1;
    21           for(int i=1;i<=n;++i)
    22             for(int j=1;j<=n;++j)
    23               sumv[i][j]=sumv[i-1][j]+sumv[i][j-1]-sumv[i-1][j-1]+vis[i][j];
    24           ITER it=Q.begin();
    25           while(it!=Q.end())
    26             {
    27                 int hav=sumv[(*it).x2][(*it).y2]-sumv[(*it).x1-1][(*it).y2]-
    28                 sumv[(*it).x2][(*it).y1-1]+sumv[(*it).x1-1][(*it).y1-1];
    29                 if(hav>=(*it).k)
    30               {
    31                 for(int i=r;i>=l;--i)
    32                   if(Ins[i].x>=(*it).x1 && Ins[i].x<=(*it).x2 &&
    33                      Ins[i].y>=(*it).y1 && Ins[i].y<=(*it).y2)
    34                        {
    35                            if(hav==(*it).k)
    36                              {
    37                                  anss[(*it).p]=Ins[i].v;
    38                                  break;
    39                              } --hav;
    40                        }
    41                 ITER t=it; ++it; Q.erase(t);
    42               }
    43             else ++it;
    44             }
    45       }
    46     int l=(sum-1)*sz+1; int r=q;
    47     for(int i=l;i<=r;++i) vis[Ins[i].x][Ins[i].y]=1;
    48     for(int i=1;i<=n;++i)
    49       for(int j=1;j<=n;++j)
    50           sumv[i][j]=sumv[i-1][j]+sumv[i][j-1]-sumv[i-1][j-1]+vis[i][j];
    51     ITER it=Q.begin();
    52     while(it!=Q.end())
    53       {
    54           int hav=sumv[(*it).x2][(*it).y2]-sumv[(*it).x1-1][(*it).y2]-
    55             sumv[(*it).x2][(*it).y1-1]+sumv[(*it).x1-1][(*it).y1-1];
    56           if(hav>=(*it).k)
    57           {
    58             for(int i=r;i>=l;--i)
    59               if(Ins[i].x>=(*it).x1 && Ins[i].x<=(*it).x2 &&
    60                  Ins[i].y>=(*it).y1 && Ins[i].y<=(*it).y2)
    61                    {
    62                      if(hav==(*it).k)
    63                        {
    64                            anss[(*it).p]=Ins[i].v;
    65                            break;
    66                        } --hav;
    67                   }
    68             ITER t=it; ++it; Q.erase(t);
    69           }
    70         else ++it;
    71       }
    72 }
    73 int main()
    74 {
    75     scanf("%d%d",&n,&m);
    76     for(int i=1;i<=n;++i)
    77       for(int j=1;j<=n;++j)
    78         {
    79             scanf("%d",&Ins[++q].v);
    80             Ins[q].x=i; Ins[q].y=j;
    81         }
    82     sort(Ins+1,Ins+q+1);
    83     for(int i=1;i<=m;++i) Q.push_back(Ask(i));
    84     makeblock();
    85     for(int i=1;i<=m;++i) printf("%d
    ",anss[i]);
    86     return 0;
    87 }
  • 相关阅读:
    Windows server 2016 解决“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同。”
    Windows Server 2016 辅助域控制器搭建
    Windows Server 2016 主域控制器搭建
    Net Framework 4.7.2 覆盖 Net Framework 4.5 解决办法
    SQL SERVER 2012更改默认的端口号为1772
    Windows下彻底卸载删除SQL Serever2012
    在Windows Server2016中安装SQL Server2016
    SQL Server 创建索引
    C#控制台或应用程序中两个多个Main()方法的设置
    Icon cache rebuilding with Delphi(Delphi 清除Windows 图标缓存源代码)
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4147429.html
Copyright © 2011-2022 走看看