zoukankan      html  css  js  c++  java
  • [BZOJ1176]Mokia

    Description

    维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.

    Input

    第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小
    接下来每行为一下三种输入之一(不包含引号):
    "1 x y a"
    "2 x1 y1 x2 y2"
    "3"
    输入1:你需要把(x,y)(第x行第y列)的格子权值增加a
    输入2:你需要求出以左下角为(x1,y1),右上角为(x2,y2)的矩阵内所有格子的权值和,并输出
    输入3:表示输入结束

    Output

    对于每个输入2,输出一行,即输入2的答案

    Sample Input

    0 4
    1 2 3 3
    2 1 1 3 3
    1 2 2 2
    2 2 2 3 4
    3

    Sample Output

    3
    5
     
    时隔五个月再做这道题又有新的理解
    首先把操作看成四个二维前缀和相加减,然后对于每个操作有三个维度:时间,$x$轴,$y$轴
    考虑对一个查询,哪些修改操作会对它产生影响,当且仅当在它之前发生且在它的左下方
    所以我们可以按照$x$轴先排序消除$x$轴的影响
    然后对归并排序时间戳使得左右两部分的操作有序
    然后按时间戳加入修改和询问就完成了
    代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define M 2000010
     6 using namespace std;
     7 int read() {
     8     char ch=getchar();int x=0;
     9     while(ch>'9'||ch<'0') ch=getchar();
    10     while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    11     return x;
    12 }
    13 int n,S,tot,qcnt,tim;
    14 int ans[M],f[M];
    15 struct ASK{int t,x,y,w,ot,id;}q[M],tmp[M];
    16 bool cmp(ASK a1,ASK a2) {
    17     if(a1.x!=a2.x) return a1.x<a2.x;
    18     if(a1.y!=a2.y) return a1.y<a2.y;
    19     return a1.id<a2.id;
    20 }
    21 void add(int loc,int v) {
    22     for(int i=loc;i<=n;i+=(i&-i)) f[i]+=v;
    23 }
    24 int query(int loc) {
    25     int ans=0;
    26     for(int i=loc;i;i-=(i&-i)) ans+=f[i];
    27     return ans;
    28 }
    29 void CDQ(int l,int r) {
    30     if(l==r) return;
    31     int mid=(l+r)>>1;
    32     CDQ(l,mid);CDQ(mid+1,r);
    33     int t1=l,t2=mid+1,now=l;
    34     while(t1<=mid||t2<=r) {
    35         if(t1<=mid&&q[t1].t<q[t2].t||t2>r) {
    36             if(q[t1].ot==1) add(q[t1].y,q[t1].w);
    37             tmp[now++]=q[t1++];
    38         }
    39         else {
    40             if(q[t2].ot==2) ans[q[t2].id]+=q[t2].w*query(q[t2].y);
    41             tmp[now++]=q[t2++];
    42         }
    43     }
    44     for(int i=l;i<=mid;i++) 
    45         if(q[i].ot==1) 
    46             add(q[i].y,-q[i].w);
    47     for(int i=l;i<=r;i++) q[i]=tmp[i];
    48 }
    49 int main() {
    50     S=read();n=read();
    51     while(1) {
    52         int opt=read();
    53         if(opt==3) break;
    54         if(opt==1) {
    55             int x=read(),y=read(),z=read();
    56             q[++tot]=(ASK){++tim,x,y,z,1};
    57         }
    58         else {
    59             int x1=read(),y1=read(),x2=read(),y2=read();
    60             ans[++qcnt]=(x2-x1+1)*(y2-y1+1)*S;
    61             q[++tot]=(ASK){++tim,x1-1,y1-1,1,2,qcnt};
    62             q[++tot]=(ASK){++tim,x2,y2,1,2,qcnt};
    63             q[++tot]=(ASK){++tim,x1-1,y2,-1,2,qcnt};
    64             q[++tot]=(ASK){++tim,x2,y1-1,-1,2,qcnt};
    65         }
    66     }
    67     sort(q+1,q+1+tot,cmp);
    68     CDQ(1,tot);
    69     for(int i=1;i<=qcnt;i++) printf("%d
    ",ans[i]);
    70     return 0;
    71 }
  • 相关阅读:
    【ASP.Net MVC3 】使用Unity 实现依赖注入
    小菜学习设计模式(五)—控制反转(Ioc)
    ASP.NET MVC中使用Unity Ioc Container
    Unity依赖注入使用详解
    单例模式实现
    Oracle书籍资料链接——更新ing
    eclipse设置控制台字体大小
    eclipse——反编译插件
    java.lang.String里面的trim()方法——删除首尾空格
    java关键词整理——思维导图
  • 原文地址:https://www.cnblogs.com/Slrslr/p/10062877.html
Copyright © 2011-2022 走看看