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 
  • 相关阅读:
    Codevs P1501二叉树的最大宽度和高度
    react 脚手架使用
    vue 学习七 组件上使用插槽
    vue 学习 cli3常用配置
    vue 学习五 深入了解components(父子组件之间的传值)
    vue 学习四 了解组件
    vue 学习二 深入vue双向绑定原理
    vue 学习一 组件生命周期
    vscode 常用插件
    解决在移动端上 click事件延迟300 毫秒的问题 fastclick.js
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3006419.html
Copyright © 2011-2022 走看看