COGS1752. [BOI2007]摩基亚Mokia CDQ

CDQ的板子题

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 2000010
using namespace std;
inline int read()
{
    int sum=0;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘)ch=getchar();
    while(ch>=‘0‘&&ch<=‘9‘)
    {
        sum=(sum<<1)+(sum<<3)+ch-‘0‘;
        ch=getchar();
    }
    return sum;
}
int Y[MAXN],W;
inline void update(int pos,int p)
{
    while(pos<=W)
    {
        Y[pos]+=p;
        pos+=pos&(-pos);
    }
}
inline int get_sum(int pos)
{
    int sum=0;
    while(pos>0)
    {
        sum+=Y[pos];
        pos-=pos&(-pos);
    }
    return sum;
}
struct QUERY
{
    int opt,id,x,y,t;
}A[200010],temp[200010];
int sz;
int Ans[10001];
int comp(const QUERY a,const QUERY b)
{
    return a.x<b.x||(a.x==b.x&&a.opt<b.opt);
}
void CDQ(int l,int r)
{
     if(l==r)return;
     int mid=(l+r)>>1;
     for(int i=l;i<=r;i++)
        if(A[i].opt)
        {
           if(A[i].id>mid)
           {
             if(A[i].t>0)
               Ans[A[i].t]+=get_sum(A[i].y);
             else
               Ans[0-A[i].t]-=get_sum(A[i].y);
           }
        }
        else
          if(A[i].id<=mid)
            update(A[i].y,A[i].t);
     for(int i=l;i<=r;i++)
        if(A[i].opt==0&&A[i].id<=mid)
            update(A[i].y,-A[i].t);
     int l1=l,l2=mid+1;
     for(int i=l;i<=r;i++)
      if(A[i].id<=mid)
       temp[l1++]=A[i];
      else
       temp[l2++]=A[i];
     for(int i=l;i<=r;i++)
      A[i]=temp[i];
     CDQ(l,mid);
     CDQ(mid+1,r);
}
int T;
void Init()
{
    W=read(),W=read();
    while(1)
    {
        int opt=read();
        if(opt==1)
        {
             A[++sz].opt=0;
             A[sz].x=read();
             A[sz].y=read();
             A[sz].id=sz;
             A[sz].t=read();
             continue;
        }
        if(opt==2)
        {
             T++;
             int X1=read(),Y1=read(),X2=read(),Y2=read();
             A[++sz].opt=1;
             A[sz].id=sz;
             A[sz].x=X2;
             A[sz].y=Y2;
             A[sz].t=T;
             if(X1!=1)
             {
               A[++sz].opt=1;
               A[sz].id=sz;
               A[sz].x=X1-1;
               A[sz].y=Y2;
               A[sz].t=-T;
             }
             if(Y1!=1)
             {
               A[++sz].opt=1;
               A[sz].id=sz;
               A[sz].x=X2;
               A[sz].y=Y1-1;
               A[sz].t=-T;
             }
             if(X1!=1&&Y1!=1)
             {
               A[++sz].opt=1;
               A[sz].id=sz;
               A[sz].x=X1-1;
               A[sz].y=Y1-1;
               A[sz].t=T;
             }
        }
        if(opt==3)break;
    }
    sort(A+1,A+sz+1,comp);
    CDQ(1,sz);
}
inline void print()
{
    for(int i=1;i<=T;i++)
     printf("%d\n",Ans[i]);
}
int main()
{
    freopen("mokia.in","r",stdin);
    freopen("mokia.out","w",stdout);
    Init();
    print();
    return 0;
}
时间: 2024-11-04 19:47:59

COGS1752. [BOI2007]摩基亚Mokia CDQ的相关文章

COJS 1752. [BOI2007]摩基亚Mokia

1752. [BOI2007]摩基亚Mokia ★★★   输入文件:mokia.in   输出文件:mokia.out   简单对比时间限制:5 s   内存限制:128 MB [题目描述] 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它能够回答形如“给定区域内有多少名用户?”的问题. 在定位系统中,世界被认为是一个W*W的正方形区域,由1*1的方格组成.每

【COGS1752】 BOI2007—摩基亚Mokia

http://cogs.pro/cogs/problem/problem.php?pid=1752 (题目链接) 题意 给出$n*n$的棋盘,单点修改,矩阵查询. Solution 离线以后CDQ分治.每一层按照$Y$排序,然后询问用前缀和拆成$4$个,树状数组维护一下就可以了. 细节 ? 代码 // cogs1752 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring

Bzoj1176:Mokia&amp;Cogs1752:[BOI2007]摩基亚Mokia

题目 Cogs 没有Bzoj的权限号 Sol 离线,\(CDQ\)分治,把询问拆成\(4\)个,变成每次求二位前缀和 那么只要一个修改操作(关键字为时间,\(x\),\(y\))都在这个询问前,就可以累计答案 那么就成了偏序问题了,直接\(CDQ\) 注意当\(x\)相等时要把修改丢在前面 # include <bits/stdc++.h> # define IL inline # define RG register # define Fill(a, b) memset(a, b, size

【BOI2007】摩基亚Mokia

P1948 - [BOI2007]摩基亚Mokia Description 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户C的位置在哪?"的问题,精确到毫米.但其真正高科技之处在于,它能够回答形如"给定区域内有多少名用户?"的问题. 在定位系统中,世界被认为是一个W * W的正方形区域,由1 * 1的方格组成.每个方格都有一个坐标(x,y),1<=x,y<=W.坐标的编号从1开始

摩基亚Mokia

P1948 - [BOI2007]摩基亚Mokia Description 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户C的位置在哪?"的问题,精确到毫米.但其真正高科技之处在于,它能够回答形如"给定区域内有多少名用户?"的问题. 在定位系统中,世界被认为是一个W * W的正方形区域,由1 * 1的方格组成.每个方格都有一个坐标(x,y),1<=x,y<=W.坐标的编号从1开始

[BOI2007]Mokia 摩基亚

upd:\((x1,y1)(x2,y2)\)表示以\((x1,y1)\)为左上端点 \((x2,y2)\)为右下端点的矩形 本来以为是一道二位树状数组的模板,但是看数据范围之后就放弃了,边界既然到了2000000,那么我们只能使用其他办法来代替树状数组 于是,CDQ分治就诞生了! 此题我们可以把问题转化成cdq分治模板 回忆一下二位树状数组是怎么求二维区间查询的:对于区间[x1,y1][x2,y2],我们把它转化成$ (1,1)(x1-1,y1-1)+(1,1)(x2,y2)-(1,1)(x1-

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

1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 3134  Solved: 1395[Submit][Status][Discuss] Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Input 第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小

BZOJ 1176 Balkan 2007 Mokia CDQ分治

题目大意:有一些操作,给一个坐标代表的点加上一个数,和求出一个矩形中的所有数的和. 思路:一眼题,二位树状数组水过. ... .. . 哪里不对?W<=2000000.逗我?这n^2能开下? 这个时候CDQ神牛又来帮助我们了. 这个题应该算是CDQ分治的模板题了吧,简单分析一下,其实不难. 写这个题之前建议写一下BZOJ 1935 SHOI 2007 Tree 园丁的烦恼 树状数组这个题,是本题的简化版. 按照正常的解法,我们应该建立一个二位的数据结构,然后分别维护两维的信息.如果用动态开点的线

BZOJ 1176 [Balkan2007]Mokia CDQ分治

题目大意: 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. POJ1195的加强版 没记错的话上午这题还没有中文题目描述的说0.0 好迅速 首先这题看到W就知道二维树状数组挂了 看到M就发现离散化了也搞不了 0.0 这题似乎是CDQ分治被发现之后第二个解决的题目...不过只有会员才知道的世界,今天反应过来刷刷... 修改和询问放在一起分治,一个询问拆分成4个,树状数组处