• AcWing250 磁力块(分块)


    本题仔细分析发现也是一个二维偏序问题,并且因为强制在线,所以不能用莫队来做,因此考虑分块的做法

    这道题,因为题目第一个要求是距离小于半径,因此我们直接算出距离后,通过对距离排序,之后分块

    这样的分块就会产生一个性质,在某些块中的所有半径都小于r,而在边界块中,则使用暴力。

    在块中我们按质量排序

    之后我们只需要给每个块分配一个指针,用于判断质量和吸力的关系,这个指针会一直往后推,不用回溯。

    这题还可以替换磁力块,其实就相当于bfs,将已经吸入的都可以当作x,y这个点,只要最后队列空了,说明就结束了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=2e5+10;
    const int mod=1e9+7;
    struct node{
        ll dis,m;
        ll r,p;
    }s[2*N+10],d[510][510];
    ll sign[5050];
    int e[5050];
    int st[5050][5050];
    int cnt[5050];
    int n,block;
    ll x,y,x2,y2;
    bool cmpa(node a,node b){
        return a.dis<b.dis;
    }
    bool cmpb(node a,node b){
        return a.m<b.m;
    }
    void init(){
        int i;
        for(i=1;i<=n;i++){
            cin>>x2>>y2>>s[i].m>>s[i].p>>s[i].r;
            s[i].dis=(x2-x)*(x2-x)+(y2-y)*(y2-y);
            s[i].r*=s[i].r;
        }
        block=sqrt(n);
        sort(s+1,s+1+n,cmpa);
        for(i=1;i<=n;i++){
            d[(i-1)/block+1][(i-1)%block]=s[i];
            sign[(i-1)/block+1]=s[i].dis;
        }
        for(i=1;i<=(n-1)/block+1;i++){
            if(i*block<=n)
                e[i]=block;
            else
                e[i]=n%block;
            sort(d[i],d[i]+e[i],cmpb);
        }
    }
    bool check(ll a,ll b){
        return a<=b;
    }
    void bfs(){
        queue<node> q;
        q.push(s[0]);
        st[0][0]=1;
        while(q.size()){
            node t=q.front();
            q.pop();
            int i;
            for(i=1;i<=(n-1)/block+1;i++){
                if(sign[i]<=t.r){
                   while(cnt[i]<e[i]&&check(d[i][cnt[i]].m,t.p)){
                        if(!st[i][cnt[i]]){
                            st[i][cnt[i]]=1;
                            q.push(d[i][cnt[i]]);
                        }
                        cnt[i]++;
                    }
                }
                else{
                    for(int j=0;j<e[i];j++){
                        if(d[i][j].dis<=t.r&&d[i][j].m<=t.p){
                            if(!st[i][j]){
                                q.push(d[i][j]);
                                st[i][j]=1;
                            }
                        }
                    }
                    break;
                }
            }
        }
    }
    int main(){
        ios::sync_with_stdio(0);
        cin>>x>>y>>s[0].p>>s[0].r>>n;
        s[0].r*=s[0].r;
        init();
        bfs();
        int i;
        ll ans=0;
        for(i=1;i<=(n-1)/block+1;i++){
            for(int j=0;j<e[i];j++){
                if(st[i][j])
                    ans++;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    雅虎笔试&面试题
    有道面试
    IBM笔试&面试
    20140916~17华宇笔试&面试
    操作系统知识梳理3-存储管理
    操作系统知识梳理2-哲学家就餐问题
    操作系统知识梳理1-概述及进程管理
    阿里面试总结
    2012-2015网易有道笔试题总结
    PostgresSQL在cmd中使用psql操作数据库
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12771699.html
Copyright © 2020-2023  润新知