CF1409E Two Platforms(线段树)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<cmath>
#include<cstring>

using namespace std;
//typedef unsigned long long ll;
typedef long long ll;
typedef pair<int, int> PII;
#define x first
#define y second
const int N = 1000007, M = 5000007;
const ll INF = 1e14;

inline void read(int &x)
{
	char c = getchar();
	while ((c < 48) || (c > 57)) c = getchar();
	x = c ^ 48;c = getchar();
	while ((c >= 48) && (c <= 57))
	{
		x = x * 10 + (c ^ 48);
		c = getchar();
	}
}

struct node{
    int l, r;
    int maxx;
}tr[N << 2];
int n, m, t, k;
int x[N], y;
int a[N];
int num[N];
int s[N];
int pre[N];

void build(int p, int l, int r){
    tr[p] = {l, r, 0};
    if(l == r){
        tr[p].maxx = s[r];
        return ;
    }
    int mid = l + r >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    tr[p].maxx = max(tr[p << 1].maxx, tr[p << 1 | 1].maxx);
}

int query(int p, int l, int r){
    if(tr[p].l >= l && tr[p].r <= r){
        return tr[p].maxx;
    }
    int mid = tr[p].l + tr[p].r >> 1;
    int res = 0;
    if(l <= mid)res = max(res, query(p << 1, l, r));
    if(r > mid)res = max(res, query(p << 1 | 1, l, r));
    return res;
}

int main(){
    scanf("%d", &t);
    while(t -- ){
        /*memset(s, 0, sizeof s);
        memset(pre, 0, sizeof pre);
        memset(num, 0, sizeof num);*/
        
        for(int i = 0; i  <= n; ++ i)
        s[i] = pre[i] = num[i] = 0;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++ i)
        scanf("%d", &x[i]), a[i] = x[i];
        
        for(int i = 1; i <= n; ++ i)
        scanf("%d", &y);
        
        sort(a + 1, a + 1 + n);
        
        int tot = unique(a + 1, a + 1 + n) - a - 1;
        for(int i = 1; i <= n; ++ i)
            num[lower_bound(a + 1, a + 1 + tot, x[i]) - a] ++ ;
        
        for(int i = 1; i <= n; ++ i)
            pre[i] = pre[i - 1] + num[i];
        for(int i = 1; i <= n; ++ i)
        //这里用upper找到大于他的第一个,他就是下一个
        //s[i]表示的是从i+1开始到最后tot
        s[i] = pre[upper_bound(a + i + 1, a + 1 + tot, a[i] + m) - a - 1] - pre[i - 1]; 
        
        build(1, 1, tot);
        
        int ans = 0;
        for(int i = 1; i <= tot; ++ i){
            ans = max(ans, s[i] + query(1, upper_bound(a + i + 1, a + 1 + tot, a[i] + m) - a, tot));
        }
        printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45697774/article/details/108475956