zoukankan      html  css  js  c++  java
  • Bzoj2639: 矩形计算

    Time Limit: 20 Sec  Memory Limit: 256 MB
    Submit: 178  Solved: 94

    Description

     输入一个n*m的矩阵,矩阵的每一个元素都是一个整数,然后有q个询问,每次询问一个子矩阵的权值。矩阵的权值是这样定义的,对于一个整数x,如果它在该矩阵中出现了p次,那么它给该矩阵的权值就贡献p2

    Input

      第一行两个整数n,m表示矩阵的规模。
      接下来n行每行m个整数,表示这个矩阵的每个元素。
      再下来一行一个整数q,表示询问个数。
      接下来q行每行四个正整数x1,y1,x2,y2,询问以第x1行第y1列和第x2行第y2列的连线为对角线的子矩阵的权值。

    Output

      输出q行每行一个整数回答对应询问。

    Sample Input

    3 4
    1 3 2 1
    1 3 2 4
    1 2 3 4
    8
    1 2 2 1
    1 1 2 1
    1 1 3 4
    1 1 1 1
    2 2 3 3
    3 4 2 2
    1 3 3 1
    2 4 3 4

    Sample Output

    8
    4
    38
    1
    8
    12
    27
    4

    HINT

    对于全部数据

      1<=n,m<=200

      q<=100000

      |矩阵元素大小|<=2*109

    Source

    分治 分块 二维莫队

    二维的莫队算法

    分块的时候按顶点坐标分块,belong= $ (x1/sqrt {n} )* sqrt m + (y1/sqrt m)$

    范围转移的时候稍有点麻烦

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #define LL long long
     7 using namespace std;
     8 const int mxn=310;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 inline void write(int x){
    16     if(x<0) putchar('-'),x=-x;
    17     if(x>9) write(x/10);
    18     putchar(x%10+'0');
    19     return;
    20 }
    21 int n,m,Q;
    22 int mp[mxn][mxn];
    23 int bas[mxn*mxn],cc=0;
    24 int cnt[mxn*mxn],hs[mxn*mxn];
    25 struct query{
    26     int x1,y1,x2,y2;
    27     int m,id;
    28     bool operator < (const query &b)const{
    29         return (m==b.m && ((x1==b.x1 && y1<b.y1) || x1<b.x1 )) || m<b.m;
    30     }
    31 }q[100010];
    32 int nowans=0,ans[100010];
    33 inline void add(int x){
    34     nowans+=cnt[x]*2+1;  ++cnt[x]; return;
    35 }
    36 inline void del(int x){
    37     nowans-=cnt[x]*2-1;  --cnt[x]; return;
    38 }
    39 void solve(){
    40     int l=1,r=0,u=1,d=0;//初始位置 
    41     int i,j;
    42     for(i=1;i<=Q;i++){
    43         while(r<q[i].y2){++r;for(j=u;j<=d;j++)add(mp[j][r]);}
    44         while(l>q[i].y1){--l;for(j=u;j<=d;j++)add(mp[j][l]);}
    45         while(d<q[i].x2){++d;for(j=l;j<=r;j++)add(mp[d][j]);}
    46         while(u>q[i].x1){--u;for(j=l;j<=r;j++)add(mp[u][j]);}
    47         //
    48         //
    49         while(r>q[i].y2){for(j=u;j<=d;j++)del(mp[j][r]);--r;}
    50         while(l<q[i].y1){for(j=u;j<=d;j++)del(mp[j][l]);++l;}
    51         while(d>q[i].x2){for(j=l;j<=r;j++)del(mp[d][j]);--d;}
    52         while(u<q[i].x1){for(j=l;j<=r;j++)del(mp[u][j]);++u;}
    53         ans[q[i].id]=nowans;
    54     }
    55     return;
    56 }
    57 int main(){
    58     int i,j;
    59     n=read();m=read();
    60     for(i=1;i<=n;i++)
    61         for(j=1;j<=m;j++){
    62             mp[i][j]=read();
    63             bas[++cc]=mp[i][j];
    64         }
    65     sort(bas+1,bas+cc+1);
    66     int ed=unique(bas+1,bas+cc+1)-bas-1;
    67     for(i=1;i<=n;i++)
    68         for(j=1;j<=m;j++){
    69             int tmp=lower_bound(bas+1,bas+ed+1,mp[i][j])-bas;
    70             mp[i][j]=tmp;
    71         }//离散化 
    72     Q=read();
    73     int sn=sqrt(n),sm=sqrt(m);
    74     for(i=1;i<=Q;i++){
    75         q[i].x1=read(); q[i].y1=read();
    76         q[i].x2=read(); q[i].y2=read();
    77         if(q[i].x1>q[i].x2)swap(q[i].x1,q[i].x2);
    78         if(q[i].y1>q[i].y2)swap(q[i].y1,q[i].y2);
    79         q[i].m=(q[i].x1/sn)*sm+(q[i].y1/sm);
    80         q[i].id=i;
    81     }
    82     sort(q+1,q+Q+1);
    83     solve();
    84     for(i=1;i<=Q;i++){
    85         write(ans[i]);
    86         puts("");
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    Matlab中的随机数生成器
    Matlab中的随机数生成器
    Matlab 函数返回矩阵
    Matlab 函数返回矩阵
    Matlab 函数返回矩阵
    矩阵同列同行复制原理
    矩阵同列同行复制原理
    Apache/RewriteRule
    使用google map v3添加经纬度信息
    评论:一站式学习C编程(升级版) (平装)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6817615.html
Copyright © 2011-2022 走看看