• [BZOJ1176][Balkan2007]Mokia cdq+树状数组


    1176: [Balkan2007]Mokia

    Time Limit: 30 Sec  Memory Limit: 162 MB
    Submit: 3134  Solved: 1395
    [Submit][Status][Discuss]

    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

    HINT

    保证答案不会超过int范围

    Source

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<algorithm>
     7 #define maxq 800000
     8 #define ll long long
     9 using namespace std;
    10 struct data {ll id,x,y,tp,f,a,p;}t[maxq],tmp[maxq];
    11 ll s,w;
    12 ll ans[maxq];
    13 int cnt;
    14 bool cmp1(data t1,data t2) {return t1.x==t2.x?t1.id<t2.id:t1.x<t2.x;}
    15 int ask;
    16 ll sum[4000000];
    17 int lowbit(int x) {return x&(-x);}
    18 bool vis[maxq];
    19 void insert(int x,ll ad) {for(int i=x;i<=w;i+=lowbit(i)) sum[i]+=ad;}
    20 ll query(int x) {
    21     ll re=0;
    22     for(int i=x;i;i-=lowbit(i)) re+=sum[i];
    23     return re;
    24 }
    25 void cdq(int l,int r) {
    26     if(l==r) return;
    27     int mid=l+r>>1;
    28     int lp=l,rp=mid+1;
    29     for(int i=l;i<=r;i++) {
    30         if(t[i].tp==2) {
    31             if(t[i].id>mid){ans[t[i].p]+=t[i].f*query(t[i].y);vis[t[i].p]=1;}
    32          }
    33         else {if(t[i].id<=mid) insert(t[i].y,t[i].a);}
    34     }
    35     for(int i=l;i<=r;i++) if(t[i].tp==1&&t[i].id<=mid) insert(t[i].y,-t[i].a);
    36     for(int i=l;i<=r;i++) {
    37         if(t[i].id<=mid) tmp[lp++]=t[i];
    38         else tmp[rp++]=t[i];
    39     }
    40     for(int i=l;i<=r;i++) t[i]=tmp[i];
    41     cdq(l,mid);cdq(mid+1,r);
    42 }
    43 void add(ll x1,ll y1,ll id,ll tp,ll f) {t[cnt].p=id;t[cnt].f=f;t[cnt].tp=tp;t[cnt].x=x1;t[cnt].y=y1;t[cnt].id=cnt;}
    44 int main() {
    45     scanf("%lld%lld",&s,&w);
    46     int tp;
    47     while(scanf("%d",&tp)) {
    48         ask++;
    49         if(tp==3) break;
    50         if(tp==1) {cnt++;scanf("%lld%lld%lld",&t[cnt].x,&t[cnt].y,&t[cnt].a);t[cnt].id=cnt;t[cnt].tp=1;}
    51         else {
    52             ll x1,y1,x2,y2;
    53             scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
    54             cnt++;add(x1-1,y1-1,ask,2,1);cnt++;add(x2,y2,ask,2,1);
    55             cnt++;add(x1-1,y2,ask,2,-1);cnt++;add(x2,y1-1,ask,2,-1);
    56             ans[ask]+=(y2-y1+1)*(x2-x1+1)*s;
    57         }
    58     }
    59     sort(t+1,t+cnt+1,cmp1);
    60     cdq(1,cnt);
    61     for(int i=1;i<=ask;i++) if(vis[i]) printf("%lld
    ",ans[i]);
    62 }
    View Code
  • 相关阅读:
    如何选择一家公司?
    教你一招最屌的阅读开源项目的姿势
    我是如何管理我的团队的?
    我面试到底问什么?
    如何正确使用开源项目?
    如何选择开源项目?
    html表格中的tr td th用法
    如何用 Java 实现 Web 应用中的定时任务?
    java定时任务实现的几种方式
    Java 定时任务 & 任务调度
  • 原文地址:https://www.cnblogs.com/wls001/p/8619185.html
Copyright © 2020-2023  润新知