二维数点

二维数点

将所有询问离线 考虑对于每一个询问 将它拆成四个点来查询前缀和

离散化 并用树状数组从下到上扫一遍 复杂度是 \(O(nlogn)\)

P2163 [SHOI2007] 园丁的烦恼

注意第四个点是 \(n=0\) \(m\ne0\) 的情况 需要特判一下

#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define inl inline
#define eb emplace_back
#define endl '\n'
#define print(x) cerr<<#x<<'='<<x<<endl
#define getchar() cin.get()
#define int long long
const int N = 2e6 + 5;
int read()
{
	int x = 0 , f = 1;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , m , cnt , ans[N] , t[N];

vector<int> lsh;
struct node { int x , y; } a[N];
struct que { int x , y , add , id; } q[N<<2];

struct Tree
{
	inl int lowbit ( int x ) { return x & -x; }
	void upd ( int x , int val ) { for ( ; x <= N - 5 ; x += lowbit(x) ) t[x] += val; }
	int query ( int x ) { int res = 0; for ( ; x ; x -= lowbit(x) ) res += t[x]; return res; }
}T;

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	n = read() , m = read();
	for ( int i = 1 ; i <= n ; i ++ ) a[i].x = read() , a[i].y = read();
	for ( int i = 1 ; i <= m ; i ++ )
	{
		int lx = read() , ly = read() , rx = read() , ry = read();
		lsh.eb(lx-1) , lsh.eb(ly-1) , lsh.eb(rx) , lsh.eb(ry);
		q[++cnt] = { lx - 1 , ly - 1 , 1 , i } , q[++cnt] = { lx - 1 , ry , -1 , i } , q[++cnt] = { rx , ly - 1 , -1 , i } , q[++cnt] = { rx , ry , 1 , i };
	}
	sort ( lsh.begin() , lsh.end() );
	lsh.erase ( unique ( lsh.begin() , lsh.end() ) , lsh.end() );
	for ( int i = 1 ; i <= n ; i ++ )
	{
		a[i].x = lower_bound ( lsh.begin() , lsh.end() , a[i].x ) - lsh.begin() + 1;
		a[i].y = lower_bound ( lsh.begin() , lsh.end() , a[i].y ) - lsh.begin() + 1;
	}
	for ( int i = 1 ; i <= cnt ; i ++ )
	{
		q[i].x = lower_bound ( lsh.begin() , lsh.end() , q[i].x ) - lsh.begin() + 1;
		q[i].y = lower_bound ( lsh.begin() , lsh.end() , q[i].y ) - lsh.begin() + 1;
	}
	sort ( a + 1 , a + n + 1 , [](const node &a , const node &b) { return a.x == b.x ? a.y < b.y : a.x < b.x; } );
	sort ( q + 1 , q + cnt + 1 , [](const que &a , const que &b) { return a.x == b.x ? a.y < b.y : a.x < b.x; } );
	int now = 1;
	for ( int i = 1 ; i <= cnt ; i ++ )
	{
		while ( now <= n && a[now].x <= q[i].x ) T.upd ( a[now].y , 1 ) , ++ now;
		ans[q[i].id] += q[i].add * T.query ( q[i].y );
	}
	for ( int i = 1 ; i <= m ; i ++ ) cout << ans[i] << endl;
	return 0;
}

P3755 [CQOI2017] 老C的任务

基本一样的题 就是树状数组向上 \(upd\) 的时候不是 \(1\) 而是对应的 \(val\)

#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define inl inline
#define eb emplace_back
#define endl '\n'
#define ls p<<1
#define rs p<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define pii pair<int,int>
#define fi first
#define se second
#define mkp make_pair
#define print(x) cerr<<#x<<'='<<x<<endl
#define getchar() cin.get()
#define int long long
const int N = 3e6 + 5;
int read()
{
	int x = 0 , f = 1;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , m , temp = 1 , ans[N] , cnt , maxn;

struct node
{
	int x , y , val;
}t[N];

struct Query
{
	int x , y , add , id;
}q[N];

struct BIT
{
	int t[N];
	inl int lowbit ( int x ) { return x & (-x); }
	void upd ( int x , int val ) { for ( ; x <= N - 5 ; x += lowbit(x) ) t[x] += val; }
	int query ( int x ) { int res = 0; for ( ; x ; x -= lowbit(x) ) res += t[x]; return res; }
}T;

vector<int> lshx , lshy;

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	n = read() , m = read();
	for ( int i = 1 ; i <= n ; i ++ ) t[i].x = read() , t[i].y = read() , t[i].val = read() , lshx.eb(t[i].x) , lshy.eb(t[i].y);
	for ( int i = 1 ; i <= m ; i ++ )
	{
		int lx = read() - 1 , ly = read() - 1 , rx = read() , ry = read();
		lshx.eb(lx) , lshy.eb(ly) , lshx.eb(rx) , lshy.eb(ry);
		q[++cnt] = { lx , ly , 1 , i } , q[++cnt] = { lx , ry , -1 , i } , q[++cnt] = { rx , ly , -1 , i } , q[++cnt] = { rx , ry , 1 , i };
	}
	sort ( t + 1 , t + n + 1 , [](const node &a , const node &b) { return a.x == b.x ? a.y < b.y : a.x < b.x; } );
	sort ( q + 1 , q + cnt + 1 , [](const Query &a , const Query &b) { return a.x == b.x ? a.y < b.y : a.x < b.x; } );
	
	sort ( lshx.begin() , lshx.end() );
	lshx.erase(unique(lshx.begin(),lshx.end()),lshx.end());
	sort ( lshy.begin() , lshy.end() );
	lshy.erase(unique(lshy.begin(),lshy.end()),lshy.end());

	for ( int i = 1 ; i <= n ; i ++ )
	{
		t[i].x = lower_bound ( lshx.begin() , lshx.end() , t[i].x ) - lshx.begin() + 1;
		t[i].y = lower_bound ( lshy.begin() , lshy.end() , t[i].y ) - lshy.begin() + 1;
	}
	for ( int i = 1 ; i <= cnt ; i ++ )
	{
		q[i].x = lower_bound ( lshx.begin() , lshx.end() , q[i].x ) - lshx.begin() + 1;
		q[i].y = lower_bound ( lshy.begin() , lshy.end() , q[i].y ) - lshy.begin() + 1;
	}
	for ( int i = 1 ; i <= cnt ; i ++ )
	{
		while ( temp <= n && t[temp].x <= q[i].x ) T.upd ( t[temp].y , t[temp].val ) , ++temp;
		ans[q[i].id] += q[i].add * T.query ( q[i].y );
	}
	for ( int i = 1 ; i <= m ; i ++ ) cout << ans[i] << endl;
	return 0;
}

posted @ 2023-09-21 19:55  Echo_Long  阅读(54)  评论(0编辑  收藏  举报