BZOJ2716天使玩偶

不会KD-tree怎么办?CQD硬搞。

建立正常的平面直角坐标系,首先我们只考虑在目标点左下角的点对目标点的贡献,由于左下点的横纵坐标都小于目标点,那么曼哈顿距离就可以化简了,绝对值去掉后,得到$x2+y2-(x1+y1)$,那么我们的目标就转化为了求横纵坐标以及时间轴都小于目标查询点的更改点所作出的贡献,这是一个三维偏序问题,我们在树状数组中维护x+y的最大值,进而即可更新答案。

可是这样做我们只是考虑了左下角点的贡献,肯定是会出错的,但是其余位置的点不容易化简绝对值,或者化简完以后的形式比较难以维护,而且个人认为分类的话码量略大。

那么我们换一个角度,如何将其余位置的点都变化到目标点的左下角。

直接翻转坐标系就行了,把所有点的横纵坐标都翻转一下,使之分别落于其他象限。那么再次调用cdq即可,注意防负下标。

这样打的好处就是比较无脑,而且正确性保障很大,但是常数这种东西还是很神奇的。(本代码不保证Bzoj可A)(其实应该不可A,因为main函数返回值是signed)

#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define int long long 
using namespace std;
const int inf=0x7fffffffffffff;
int read(){
    int sum=0,f=1;char x=getchar();
    while(x<'0'||x>'9'){
        if(x=='-') f=-1;
        x=getchar();
    }while(x>='0'&&x<='9'){
        sum=sum*10+x-'0';
        x=getchar();
    }return sum*f;
}
struct rec{
    int x,y,t,id,ty;
    friend bool operator < (const rec &a,const rec &b){
        if(a.t==b.t){
            if(a.x==b.x) return a.y<b.y;
            else return a.x<b.x;
        }else return a.t<b.t;
    }
}q[6005000],tmp[6005000];
int n,m,kind,Max,ans[3005000],tr[10005000],_time=1,mk[10005000];
void change(int pos,int val){
    if(!pos) return ;
    for(int i=pos;i<=Max;i+=lowbit(i))
        if(mk[i]!=_time){
            mk[i]=_time;
            tr[i]=val;
        }
        else tr[i]=max(tr[i],val);
}
int ask(int pos){
    int ans=-inf;
    for(int i=pos;i;i-=lowbit(i))
        if(mk[i]==_time) ans=max(ans,tr[i]);
    return ans;
}
void cdq(int l,int r){
    if(l==r) return ;
    int mid=l+r>>1;
    cdq(l,mid);cdq(mid+1,r);
    int i=l,j=mid+1,tot=l;
    while(i<=mid&&j<=r){
        if(q[i].x<=q[j].x){
            tmp[tot]=q[i];
            if(!q[i].ty)
                change(q[i].y,q[i].x+q[i].y);
            ++tot;++i;
        }else {
            tmp[tot]=q[j];
            if(q[j].ty)
                ans[q[j].id]=min(ans[q[j].id],q[j].x+q[j].y-ask(q[j].y));
            ++tot;++j;
        }
    }
    while(i<=mid){
        tmp[tot]=q[i];
//        if(!q[i].ty)
//            change(q[i].y,q[i].x+q[i].y);
        ++tot;++i;
    }
    while(j<=r){
        tmp[tot]=q[j];
        if(q[j].ty)
            ans[q[j].id]=min(ans[q[j].id],q[j].x+q[j].y-ask(q[j].y));
        ++tot;++j;
    }
/*    for(int i=1;i<=Max;i++)
        cout<<tr[i]<<" ";cout<<endl;*/
//    for(int k=l;k<=mid;k++) 
    //    if(!q[i].ty) del(q[k].y);
/*    for(int i=1;i<=Max;i++)
        cout<<tr[i]<<" ";cout<<endl;*/
    _time++;
//    if(_time>=10000000000) _time=1;
    for(int k=l;k<=r;k++) q[k]=tmp[k];
}
signed main(){
    n=read();m=read();
    for(int i=1;i<=n;i++){
        q[i].x=read()+1;q[i].y=read()+1;
        q[i].t=0;q[i].ty=0;
        Max=max(Max,max(q[i].x,q[i].y));
    }
    for(int i=1;i<=m;i++){
        kind=read();
        if(kind&1){
            q[i+n].x=read()+1;q[i+n].y=read()+1;
            q[i+n].t=i;q[i].ty=0;
        }else {
            q[i+n].x=read()+1;q[i+n].y=read()+1;
            q[i+n].t=i;q[i+n].ty=1;
            q[i+n].id=++ans[0];
            ans[ans[0]]=inf;
        }
        Max=max(Max,max(q[i+n].x,q[i+n].y));
    }n+=m;
//    cout<<"Max="<<Max<<endl;
    sort(q+1,q+n+1);
    cdq(1,n);
/*    for(int i=1;i<=n;i++)
        cout<<q[i].t<<" "<<q[i].x<<" "<<q[i].y<<endl;*/
    for(int i=1;i<=n;i++) q[i].x=-q[i].x+Max+1;
    sort(q+1,q+1+n);
/*    for(int i=1;i<=n;i++)
        cout<<q[i].t<<" "<<q[i].x<<" "<<q[i].y<<endl;*/
    cdq(1,n);
    for(int i=1;i<=n;i++) q[i].y=-q[i].y+Max+1;
    sort(q+1,q+1+n);
    cdq(1,n);
    for(int i=1;i<=n;i++) q[i].x=-q[i].x+Max+1;
    sort(q+1,q+n+1);
    cdq(1,n);
    for(int i=1;i<=ans[0];i++)
        printf("%lld\n",ans[i]);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/Yu-shi/p/11252540.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值