zoukankan      html  css  js  c++  java
  • BZOJ2683 简单题

     题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2683

    题目大意:二维平面上,单点修改权值,区间询问权值和。

    CDQ分治裸题。

    话说我今天才学CDQ分治,还想了好久才会写的。

    将询问拆成4个操作,CDQ分治搞一搞就好了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #define inf 1<<30
     6 #define maxn 500005
     7 #define maxm 800005
     8 using namespace std;
     9 int n,tot,m,cnt,pos[maxm],t[maxn],ans[maxm];
    10 struct fuck{int x,y,op,id,v;}e[maxm];
    11 bool comp(fuck a,fuck b){
    12     if(a.x==b.x) return a.y<b.y;
    13     return a.x<b.x;
    14 }
    15 void change(int x,int y){for(int i=x;i<=m;i+=i&-i) t[i]+=y;}
    16 int query(int x){int y=0; for(int i=x;i;i-=i&-i) y+=t[i]; return y;}
    17 void solve(int l,int r){
    18     if(l==r) return;
    19     int mid=(l+r)/2;
    20     solve(l,mid); solve(mid+1,r);
    21     sort(e+l,e+mid+1,comp); sort(e+mid+1,e+r+1,comp);
    22     int i=l,j=mid+1,last=0;
    23     while(j<=r){
    24         while(i<=mid&&e[i].op==2) i++;
    25         while(j<=r&&e[j].op==1) j++;
    26         if(i<=mid&&e[i].x<=e[j].x) change(e[i].y,e[i].v),last=i++;
    27         else if(j<=r) ans[e[j].id]+=query(e[j].y),++j;
    28     }
    29     for(int i=l;i<=last;i++) if(e[i].op==1) change(e[i].y,-e[i].v);
    30 }
    31 int main(){
    32     scanf("%d",&n);
    33     int type,x1,x2,y1,y2;
    34     while(1){
    35         scanf("%d",&type);
    36         if(type==1){e[++m].op=1; e[m].id=m; scanf("%d%d%d",&e[m].x,&e[m].y,&e[m].v);}
    37         else if(type==2){
    38             pos[++cnt]=m;
    39             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    40             e[++m].op=2; e[m].x=x2; e[m].y=y2; e[m].id=m;
    41             e[++m].op=2; e[m].x=x1-1; e[m].y=y1-1; e[m].id=m;
    42             e[++m].op=2; e[m].x=x2; e[m].y=y1-1; e[m].id=m;
    43             e[++m].op=2; e[m].x=x1-1; e[m].y=y2; e[m].id=m;
    44         }
    45         else break;
    46     }
    47     solve(1,m);
    48     for(int i=1;i<=cnt;i++) printf("%d
    ",ans[pos[i]+1]+ans[pos[i]+2]-ans[pos[i]+3]-ans[pos[i]+4]);
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    最小生成树模板(Prim+Kruskal)
    最短路模板(Dij+Floyd)
    LeetCode双周赛#33 题解
    CSS3 学习笔记(中)
    拓扑排序小测试
    串和矩阵压缩的小测试
    树的相关小测试 题解
    Leetcode 周赛#202 题解
    HTML5 学习笔记
    Leetcode 双周赛#32 题解
  • 原文地址:https://www.cnblogs.com/longshengblog/p/5506400.html
Copyright © 2011-2022 走看看