Codeforces 1045G AI robots [CDQ分治]

时间:2022-06-29 16:55:15

洛谷

Codeforces


简单的CDQ分治题。

由于对话要求互相看见,无法简单地用树套树切掉,考虑CDQ分治。

按视野从大到小排序,这样只要右边能看见左边就可以保证互相看见。

发现\(K\)固定,那么左右按智商排序、位置离散化之后可以\(two\;pointers\)一下,套个树状数组,就做完了。

由于复杂度瓶颈在树状数组,没必要归并,可以直接\(sort\)。

复杂度应该是\(O(n\log^2 n)\)。


#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define sz 301001
typedef long long ll;
template<typename T>
inline void read(T& t)
{
t=0;char f=0,ch=getchar();
double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.')
{
ch=getchar();
while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();
}
t=(f?-t:t);
}
template<typename T,typename... Args>
inline void read(T& t,Args&... args){read(t); read(args...);}
void file()
{
#ifndef ONLINE_JUDGE
freopen("a.txt","r",stdin);
#endif
}
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std; int n,K;
ll ans;
int A[sz];
struct hh{int p,l,r,q,len;}a[sz];
inline bool cmp(const hh &x,const hh &y){return x.len>y.len;}
inline bool cmp2(const hh &x,const hh &y){return x.q<y.q;} int sum[sz];
void add(int x,int v){while (x<=n) sum[x]+=v,x+=(x&(-x));}
int query(int x){int ret=0;while (x) ret+=sum[x],x-=(x&(-x));return ret;}
int query(int l,int r){return query(r)-query(l-1);} void solve(int l,int r)
{
if (l==r) return;
int mid=(l+r)>>1;
solve(l,mid);solve(mid+1,r);
int L=l,R=l-1;
rep(i,mid+1,r)
{
while (L<=mid&&a[i].q-a[L].q>K) add(a[L].p,-1),++L;
while (R<mid&&a[R+1].q-a[i].q<=K) ++R,add(a[R].p,1);
ans+=query(a[i].l,a[i].r);
}
rep(i,L,R) add(a[i].p,-1);
sort(a+l,a+r+1,cmp2);
} int main()
{
file();
read(n,K);
int c;
rep(i,1,n) read(a[i].p,a[i].len,a[i].q),A[i]=a[i].p;
sort(A+1,A+n+1);c=unique(A+1,A+n+1)-A-1;
rep(i,1,n)
a[i].l=lower_bound(A+1,A+c+1,a[i].p-a[i].len)-A,
a[i].r=upper_bound(A+1,A+c+1,a[i].p+a[i].len)-A-1,
a[i].p=lower_bound(A+1,A+c+1,a[i].p)-A;
sort(a+1,a+n+1,cmp);
solve(1,n);
cout<<ans;
return 0;
}