二维数点
二维数点
将所有询问离线 考虑对于每一个询问 将它拆成四个点来查询前缀和
离散化 并用树状数组从下到上扫一遍 复杂度是 \(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;
}