zoukankan      html  css  js  c++  java
  • ZOJ 3018

    题意:

    op:对平面上任意一个点操作+v;

    query:询问矩形[x1,y1,x2,y2]里面所有点v的总和;

    矩形大小为20000*20000,比赛的时候看到这道题目第一直觉就是二维树状数组,但范围太大会mle,二维线段树也会mle(之后树套树的二维线段树),比赛结束后各种询问;

    方法1:

    用map<int,int> mp[N];来减少内存的,只在用到的地方开,没有用到的地方就不开;

    View Code
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<map>
     6 #include<cstdlib>
     7 #include<cmath>
     8 #include<vector>
     9 #include<cstdlib>
    10 using namespace std;
    11 const int N=20000+10;
    12 map<int,int > mp[N];
    13 char s[100];
    14 int lowbit(int x){
    15     return x&-x;
    16 }
    17 void update(int x,int y,int v){
    18     for (int i=x;i<N;i+=lowbit(i)){
    19         for (int j=y;j<N;j+=lowbit(j)){
    20             mp[i][j]+=v;
    21         }
    22     }
    23 }
    24 int sum(int x,int y){
    25     int ret=0;
    26     for (int i=x;i;i-=lowbit(i)){
    27         for (int j=y;j;j-=lowbit(j)){
    28             if (mp[i].find(j)!=mp[i].end()){
    29                 ret+=mp[i][j];
    30             }
    31         }
    32     }
    33     return ret;
    34 }
    35 int  getsum(int x1,int y1,int x2,int y2){
    36 //    cout<<"---- "<<sum(x2,y2)<<" "<<sum(x1-1,y2)<<" "<<sum(x2,y1-1)<<" "<<sum(x1-1,y1-1)<<endl;
    37     return sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1);
    38 }
    39 int main(){
    40     int flag=0;
    41     int f=0;
    42     while (gets(s)){
    43         for (int i=0;i<N;i++) mp[i].clear();
    44         while (1){
    45             if (s[0]=='I'){
    46                 flag=1;
    47             }else
    48             if (s[0]=='Q'){
    49                 flag=2;
    50             }else 
    51             if (s[0]=='E') break;
    52             else if (s[0]>='0' && s[0]<='9'){
    53                 int x1,x2,y1,y2,v;
    54                 if (flag==1){
    55                     sscanf(s,"%d%d%d",&x1,&y1,&v);
    56                 //    cout<<"** "<<x1<<" "<<y1<<" "<<v<<endl;
    57                     update(x1,y1,v);
    58                 }else if (flag==2){
    59                     sscanf(s,"%d%d%d%d",&x1,&x2,&y1,&y2);
    60                 //    cout<<"/// "<<x1<<" "<<x2<<" "<<y1<<" "<<y2<<endl;
    61                     printf("%d\n",getsum(x1,y1,x2,y2));
    62                 }
    63             }
    64             gets(s);
    65         }
    66     }
    67     return 0;
    68 }
    1 3243951 2013-04-07 20:24:28 Accepted  3018 C++ 2800 15968 Rabbit 

    但是时间有点慢;

    方法2:

    用矩阵树,即二维线段树的另外一种表示方法;

    每个点表示一个矩阵,每个结点有4个结点,4个结点分别表示把这个矩阵划分成四个小矩阵,即左上,左下,右上,右下;

    View Code
      1 /*
      2 每个结点
      3 struct node{
      4     int l,r,d,u;
      5     int sum;//要维护的结点的信息;
      6     int ch[4];//四个小矩阵的标号;
      7 }T[Maxn];
      8 更新基本同一维线段树,
      9 void update(int l,int r,int d,int u,int rt,int v){
     10     if (l<=T[rt].l && T[rt].r<=r && d<=T[rt].d && T[rt].u<=u){
     11         T[rt].sum+=v;
     12         return;
     13     }
     14 };
     15 int query(int l,int r,int d,int u,int rt){
     16     if (l<=T[rt].l && T[rt].r<=r && d<=T[rt].d && T[rt].u<=u){
     17         return T[rt].sum;
     18     }
     19 };
     20 为了节省空间,只对用到的结点申请内存;
     21 
     22 */
     23 #include<cstdio>
     24 #include<cstdlib>
     25 #include<cstring>
     26 #include<algorithm>
     27 #include<iostream>
     28 #include<map>
     29 #include<vector>
     30 #include<set>
     31 #include<bitset>
     32 #include<string>
     33 #include<cmath>
     34 using namespace std;
     35 const int N=20000*15;
     36 struct node{
     37     int l,r,d,u,sum;
     38     int ch[4];
     39     node(){}
     40     node(int a,int b,int c,int e,int f):l(a),r(b),d(c),u(e),sum(f){}
     41 }T[N];
     42 
     43 int idx;
     44 int Newnode(int l,int r,int d,int u){
     45     idx++;
     46     T[idx]=node(l,r,d,u,0);
     47     memset(T[idx].ch,0,sizeof(T[idx].ch));
     48     return idx;
     49 }
     50 void update(int x,int y,int rt,int v){
     51     if (T[rt].l==T[rt].r && T[rt].u==T[rt].d){
     52         T[rt].sum+=v;
     53         return;
     54     }
     55     int m1=(T[rt].l+T[rt].r)>>1;
     56     int m2=(T[rt].u+T[rt].d)>>1;
     57     if (x<=m1 && y<=m2){//左下
     58         if (T[rt].ch[0]==0){
     59             T[rt].ch[0]=Newnode(T[rt].l,m1,T[rt].d,m2);
     60         }
     61         update(x,y,T[rt].ch[0],v);
     62     }
     63     if (x<=m1 && y>m2){//左上
     64         if (T[rt].ch[1]==0){
     65             T[rt].ch[1]=Newnode(T[rt].l,m1,m2+1,T[rt].u);
     66         }
     67         update(x,y,T[rt].ch[1],v);
     68     }
     69     if (x>m1 && y<=m2){//右下
     70         if (T[rt].ch[2]==0){
     71             T[rt].ch[2]=Newnode(m1+1,T[rt].r,T[rt].d,m2);
     72         }
     73         update(x,y,T[rt].ch[2],v);
     74     }
     75     if (x>m1 && y>m2){//右上
     76         if (T[rt].ch[3]==0){
     77             T[rt].ch[3]=Newnode(m1+1,T[rt].r,m2+1,T[rt].u);
     78         }
     79         update(x,y,T[rt].ch[3],v);
     80     }
     81     T[rt].sum=0;//合并
     82     for (int i=0;i<4;i++){
     83         int c=T[rt].ch[i];
     84         T[rt].sum+=T[c].sum;
     85     }
     86 }
     87 int query(int l,int r,int d,int u,int rt){
     88     if (l<=T[rt].l && T[rt].r<=r && d<=T[rt].d && T[rt].u<=u){
     89         return T[rt].sum;
     90     }
     91     int m1=(T[rt].l+T[rt].r)>>1;
     92     int m2=(T[rt].u+T[rt].d)>>1;
     93     int ret=0;
     94     if (l<=m1 && d<=m2){
     95         if (T[rt].ch[0]!=0){
     96             ret+=query(l,r,d,u,T[rt].ch[0]);
     97         }
     98     }
     99     if (l<=m1 && m2<u){
    100         if (T[rt].ch[1]!=0){
    101             ret+=query(l,r,d,u,T[rt].ch[1]);
    102         }
    103     }
    104     if (m1< r && d<=m2){
    105         if (T[rt].ch[2]!=0){
    106             ret+=query(l,r,d,u,T[rt].ch[2]);
    107         }
    108     }
    109     if (m1< r && m2< u){
    110         if (T[rt].ch[3]!=0){
    111             ret+=query(l,r,d,u,T[rt].ch[3]);
    112         }
    113     }
    114     return ret;
    115 }
    116 char s[100];
    117 int main(){
    118     int flag=0;
    119     while (gets(s)){
    120         idx=0;
    121         Newnode(1,20000,1,20000);
    122         while (1){
    123             if (s[0]=='I'){
    124                 flag=1;
    125             }else
    126             if (s[0]=='Q'){
    127                 flag=2;
    128             }else
    129             if (s[0]=='E') break;
    130             else if (s[0]>='0' && s[0]<='9'){
    131                 int x1,x2,y1,y2,v;
    132                 if (flag==1){
    133                     sscanf(s,"%d%d%d",&x1,&y1,&v);
    134                 //    cout<<"** "<<x1<<" "<<y1<<" "<<v<<endl;
    135                     update(x1,y1,1,v);
    136                 //    cout<<"++++ "<<T[1].sum<<endl;
    137                 }else if (flag==2){
    138                     sscanf(s,"%d%d%d%d",&x1,&x2,&y1,&y2);
    139                     //cout<<"/// "<<x1<<" "<<x2<<" "<<y1<<" "<<y2<<endl;
    140                     printf("%d\n",query(x1,x2,y1,y2,1));
    141                 }
    142             }
    143             gets(s);
    144         }
    145     }
    146     return 0;
    147 }
    1 3244125 2013-04-07 22:45:19 Accepted  3018 C++ 670 10732 Rabbit 
  • 相关阅读:
    Hadoop 学习笔记 (十) hadoop2.2.0 生产环境部署 HDFS HA Federation 含Yarn部署
    hadoop 2.x 安装包目录结构分析
    词聚类
    Hadoop 学习笔记 (十一) MapReduce 求平均成绩
    Hadoop 学习笔记 (十) MapReduce实现排序 全局变量
    Hadoop 学习笔记 (九) hadoop2.2.0 生产环境部署 HDFS HA部署方法
    Visual Studio Code 快捷键大全(Windows)
    Eclipse安装教程 ——史上最详细安装Java &Python教程说明
    jquery操作select(取值,设置选中)
    $.ajax 中的contentType
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3006419.html
Copyright © 2011-2022 走看看