• CF1045G AI robots(动态开点线段树)


    题意

    火星上有$N$个机器人排成一行,第$i$个机器人的位置为$x_{i}$,视野为$r_{i}$,智商为$q_{i}$。我们认为第$i$个机器人可以看到的位置是$[x_{i}-r_{i},x_{i}+r_{i}]$。如果一对机器人相互可以看到,且它们的智商$q_{i}$的差距不大于$K$,那么它们会开始聊天。 为了防止它们吵起来,请计算有多少对机器人可能会聊天。

    题解

    先膜一下大佬->这里

    我们先按视野降序排序,这样一个一个考虑,如果后面的能看到前面,那前面的也肯定能看到后面

    这样,就是对于每一个机器人,在他前面有几个智商在$[q-k,q+k]$,位置在$[x-r,x+r]$

    那么把这个东西看做一个矩形覆盖就可以了

    然后因为智商这一维维数很小,我们可以对每一个智商开一个动态开点线段树,然后一个一个扫过去统计答案就可以了

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<map>
     6 #define ll long long
     7 using namespace std;
     8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     9 char buf[1<<21],*p1=buf,*p2=buf;
    10 inline int read(){
    11     #define num ch-'0'
    12     char ch;bool flag=0;int res;
    13     while(!isdigit(ch=getc()))
    14     (ch=='-')&&(flag=true);
    15     for(res=num;isdigit(ch=getc());res=res*10+num);
    16     (flag)&&(res=-res);
    17     #undef num
    18     return res;
    19 }
    20 const int N=1e5+5;
    21 int n,k,m,b[N*3];ll res;
    22 map<int,int> rt;int L[N<<5],R[N<<5],sum[N<<5],cnt=0;
    23 void update(int p,int l,int r,int x){
    24     ++sum[p];if(l==r) return;
    25     int mid=(l+r)>>1;
    26     if(x<=mid) update(L[p]=L[p]?L[p]:++cnt,l,mid,x);
    27     else update(R[p]=R[p]?R[p]:++cnt,mid+1,r,x);
    28 }
    29 int query(int p,int l,int r,int ql,int qr){
    30     if(ql<=l&&qr>=r||p==0) return sum[p];
    31     int mid=(l+r)>>1,res=0;
    32     if(ql<=mid) res+=query(L[p],l,mid,ql,qr);
    33     if(qr>mid) res+=query(R[p],mid+1,r,ql,qr);
    34     return res;
    35 }
    36 inline void ins(int q,int x){
    37     if(rt.count(q)==0) rt[q]=++cnt;
    38     update(rt[q],1,m,x);
    39 }
    40 inline int get(int q,int ql,int qr){
    41     if(rt.count(q)==0) return 0;
    42     return query(rt[q],1,m,ql,qr);
    43 }
    44 struct node{
    45     int x,r,q;
    46     node(){}
    47     node(int x,int r,int q):x(x),r(r),q(q){}
    48     inline bool operator <(const node &b)const
    49     {return r>b.r;}
    50 }a[N];
    51 int main(){
    52 //    freopen("testdata.in","r",stdin);
    53     n=read(),k=read();
    54     for(int i=1;i<=n;++i){
    55         int x=read(),r=read(),q=read();
    56         a[i]=node(x,r,q);
    57         b[++m]=x,b[++m]=x-r,b[++m]=x+r;
    58     }
    59     sort(b+1,b+1+m),m=unique(b+1,b+1+m)-b-1;
    60     sort(a+1,a+1+n);
    61     for(int i=1;i<=n;++i){
    62         int l=lower_bound(b+1,b+1+m,a[i].x-a[i].r)-b;
    63         int r=lower_bound(b+1,b+1+m,a[i].x+a[i].r)-b;
    64         int x=lower_bound(b+1,b+1+m,a[i].x)-b;
    65         for(int j=a[i].q-k;j<=a[i].q+k;++j)
    66         res+=get(j,l,r);
    67         ins(a[i].q,x);
    68     }
    69     printf("%lld
    ",res);
    70     return 0;
    71 }
  • 相关阅读:
    Animation用法
    英文口语及书写常用句型汇总1
    Jqplot使用总结之二(双Y轴)
    SqlServer扩展存储过程
    SQL Server常见基础操作
    C# 利用ITextSharp导出PDF文件
    go常量
    ARP协议
    go数组
    go基本数据类型
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9749892.html
Copyright © 2020-2023  润新知