洛谷 P4390 [BOI2007]Mokia 摩基亚 解题报告

本文详细解析了P4390[BOI2007]Mokia摩基亚题目,介绍了如何通过容斥原理和树状数组解决二维区域用户数量查询问题,包括输入输出格式、算法思路和代码实现。

P4390 [BOI2007]Mokia 摩基亚

题目描述

摩尔瓦多的移动电话公司摩基亚(\(Mokia\))设计出了一种新的用户定位系统。和其他的定位系统一样,它能够迅速回答任何形如“用户\(C\)的位置在哪?”的问题,精确到毫米。但其真正高科技之处在于,它能够回答形如“给定区域内有多少名用户?”的问题。

在定位系统中,世界被认为是一个\(W\times W\)的正方形区域,由\(1\times1\)的方格组成。每个方格都有一个坐标\((x,y)\)\(1\le x,y\le W\)。坐标的编号从\(1\)开始。对于一个\(4\times4\)的正方形,就有\(1\le x\le 4,1\le y\le 4\)(如图):

请帮助\(Mokia\)公司编写一个程序来计算在某个矩形区域内有多少名用户。

输入输出格式

输入格式:

有三种命令,意义如下:

命令 参数 意义

  • 0 W 初始化一个全零矩阵。本命令仅开始时出现一次。
  • 1 x y A 向方格\((x,y)\)中添加\(A\)个用户。\(A\)是正整数。
  • 2 X1 Y1 X2 Y2 查询\(X_1\le x\le X_2,Y_1\le y\le Y_2\)所规定的矩形中的用户数量
  • 3 无参数 结束程序。本命令仅结束时出现一次。

输出格式:

对所有命令\(2\),输出一个一行整数,即当前询问矩形内的用户数量。

说明

对于所有数据:

\(1\le W\le 2000000\)
\(1\le X_1\le X_2\le W\)
\(1\le Y_1\le Y_2\le W\)
\(1\le x,y\le W\)
\(0<A\le 10000\)
命令\(1\)不超过\(160000\)个。
命令\(2\)不超过\(10000\)个。


之前做了个园丁的题目,是所有询问在修改之后的。

于是直接把四维偏序的一维搞成区间操作\(O(n\log^2n)\)水过去了。

然后这个题就萎掉了,想了一会儿还是三个\(\log\),于是打算拿树套树水过去。

结果套的线段树\(MLE\)了,无语...

然后看了看正解,发现直接对矩形容斥就可以了。

就是把一个矩形\((a,b),(c,d)\)拆成\((1,1),(a-1,b-1)\)\((1,1),(a-1,d)\)\((1,1),(c,b-1)\)\((1,1),(c,d)\)四个做。

然后就又成了三维偏序...


Code:

#include <cstdio>
#include <algorithm>
const int N=2e5+10;
int n,m,k,op,ans[N],s[N<<2],dx[N<<2],cntx,dy[N<<2],cnty;
void add(int x,int d){while(x<=cnty)s[x]+=d,x+=x&-x;}
int ask(int x){int sum=0;while(x)sum+=s[x],x-=x&-x;return sum;}
struct node
{
    int a,b,c,op;
    bool friend operator <(node n1,node n2)
    {
        return n1.a==n2.a?n1.op<n2.op:n1.a<n2.a;
    }
}q[N],qs[N];
void CDQ(int l,int r)
{
    if(l==r) return;
    int mid=l+r>>1;
    CDQ(l,mid),CDQ(mid+1,r);
    int lp=l,rp=mid+1,loc=l-1;
    while(lp<=mid&&rp<=r)
    {
        if(q[lp]<q[rp])
        {
            if(!q[lp].op) add(q[lp].b,q[lp].c);
            qs[++loc]=q[lp++];
        }
        else
        {
            if(q[rp].op) ans[q[rp].op]+=q[rp].c*ask(q[rp].b);
            qs[++loc]=q[rp++];
        }
    }
    while(rp<=r)
    {
        if(q[rp].op) ans[q[rp].op]+=q[rp].c*ask(q[rp].b);
        qs[++loc]=q[rp++];
    }
    for(int i=l;i<lp;i++) if(!q[i].op) add(q[i].b,-q[i].c);
    while(lp<=mid) qs[++loc]=q[lp++];
    for(int i=l;i<=r;i++) q[i]=qs[i];
}
int main()
{
    scanf("%d%d",&n,&n);
    scanf("%d",&op);int a,b,c,d;
    while(op!=3)
    {
        if(op==1)
        {
            ++m;
            scanf("%d%d%d",&q[m].a,&q[m].b,&q[m].c);
            dx[++cntx]=q[m].a,dy[++cnty]=q[m].b;
        }
        else
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            dx[++cntx]=a-1,dy[++cnty]=b-1,dx[++cntx]=c,dy[++cnty]=d;
            ++k;
            q[++m]={a-1,b-1,1,k};
            q[++m]={a-1,d,-1,k};
            q[++m]={c,b-1,-1,k};
            q[++m]={c,d,1,k};
        }
        scanf("%d",&op);
    }
    std::sort(dx+1,dx+1+cntx);
    std::sort(dy+1,dy+1+cnty);
    cntx=std::unique(dx+1,dx+1+cntx)-dx-1;
    cnty=std::unique(dy+1,dy+1+cnty)-dy-1;
    for(int i=1;i<=m;i++)
    {
        q[i].a=std::lower_bound(dx+1,dx+1+cntx,q[i].a)-dx;
        q[i].b=std::lower_bound(dy+1,dy+1+cnty,q[i].b)-dy;
    }
    CDQ(1,m);
    for(int i=1;i<=k;i++) printf("%d\n",ans[i]);
    return 0;
}

2018.11.27

转载于:https://www.cnblogs.com/butterflydew/p/10028401.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值