使用线段树出现神秘错误,样例5第一个数错,第二个数全对
查看原帖
使用线段树出现神秘错误,样例5第一个数错,第二个数全对
470590
LikAzusa_楼主2024/10/30 19:12

rt 马蜂较为良好

#include <bits/stdc++.h>

using namespace std;

inline int read()
{
	int x = 0, f = 1; char c = getchar();
	while(c > '9' || c < '0') {if(c == '-') f = -1; c = getchar();}
	while(c <= '9' && c >= '0') {x = x * 10 + c - '0'; c = getchar();}
	return x * f;
}

const int maxn = 1e5 + 10;
const int N = 1e6 + 10;
struct Node
{
	int l, r;
	int maxa;
	int sum;
	#define lson (id<<1)
	#define rson (id<<1|1)
}t[N<<2];
struct node
{
	int l, r;
	int flag;
	int d, v, a;
}q[maxn];
int n, m, L, V;
int T;
int det[N];
int ans1, ans2;
bool cmp(node a, node b) {return a.r < b.r;}
void update(int id)
{
	t[id].maxa = max(t[lson].maxa, t[rson].maxa);
	t[id].sum = max(t[lson].sum, t[rson].sum);
}
void build(int id, int L, int R)
{
	t[id].l = L; t[id].r = R;
	if(L == R)
	{
		if(!det[L]) t[id].maxa = 0;
		else t[id].maxa = L;
		t[id].sum = 0;
		return;
	}
	int mid = L + R >> 1;
	build(lson, L, mid);
	build(rson, mid+1, R);
	update(id);
}
void printtree(int id)
{
	printf("id:%d, l:%d, r:%d, maxa:%d, sum:%d\n", id, t[id].l, t[id].r, t[id].maxa, t[id].sum);
	if(t[id].l == t[id].r) return;
	printtree(lson);
	printtree(rson);
}
void change(int id, int L, int R)
{
	if(t[id].l == t[id].r)
	{
		t[id].sum = 1;
		return;
	}
	int mid = t[id].l + t[id].r >> 1;
	if(L <= mid) change(lson, L, R);
	if(R > mid) change(rson, L, R);
	update(id);
}
int query(int id, int L, int R)
{
	if(t[id].l >= L && t[id].r <= R) return t[id].sum;
	int mid = t[id].l + t[id].r >> 1, ans = 0;
	if(L <= mid) ans = max(ans, query(lson, L, R));
	if(R > mid) ans = max(ans, query(rson, L, R));
	return ans;
}
int find(int id, int L, int R)
{
	if(t[id].l >= L && t[id].r <= R) return t[id].maxa;
	int mid = t[id].l + t[id].r >> 1, ans = 0;
	if(L <= mid) ans = max(ans, find(lson, L, R));
	if(R > mid) ans = max(ans, find(rson, L, R));
	return ans;
}

int main()
{
//	freopen("detect4.in", "r", stdin);
//	freopen("detect.out", "w", stdout);
	T = read();
	while(T--)
	{
		ans1 = ans2 = 0;
		memset(q, 0, sizeof(q));
		n = read(), m = read(), L = read(), V = read();
		for(int i = 1; i <= L+1; i++) det[i] = 0;
		for(int i = 1; i <= n; i++)
		{
			q[i].d = read(), q[i].v = read(), q[i].a = read();
			if(q[i].v > V)
			{
				q[i].flag = 1;
				q[i].l = q[i].d+1;
				if(q[i].a >= 0) q[i].r = L+1;
				else
				{
					double dis = (double)((V * V) - (q[i].v * q[i].v)) / (double)(2 * q[i].a);
					if(dis != floor(dis)) q[i].r = q[i].d + (int)floor(dis) + 1;
					else q[i].r = q[i].d + (int)dis;
				}
			}
			else if(q[i].v == V)
			{
				if(q[i].a > 0)
				{
					if(q[i].d == L) continue;
					q[i].flag = 1;
					q[i].l = q[i].d+2;
					q[i].r = L+1;
				}
			}
			else
			{
				if(q[i].a > 0)
				{
					double dis = (double)((V * V) - (q[i].v * q[i].v)) - (double)(2 * q[i].a);
					if((double)q[i].d+dis+1 <= (double)L+1)
					{
						q[i].flag = 1;
						if(dis != ceil(dis)) q[i].l = q[i].d+(int)ceil(dis)+1;
						else q[i].l = q[i].d+(int)dis+2;
						q[i].r = L+1;
					}
				}
			}
		}
		for(int i = 1; i <= m; i++) {int x = read(); det[x+1] = 1;}
		build(1, 1, L+1);
//		printtree(1);
		sort(q+1, q+n+1, cmp);
//		for(int i = 1; i <= n; i++)
//		{
//			cout << q[i].id << ":";
//			cout << q[i].l << " " << q[i].r << " " << q[i].flag << endl;
//		}
		for(int i = 1; i <= n; i++)
		{
			if(!q[i].flag) continue;
			int l = q[i].l, r = q[i].r;
			int pos = find(1, l, r);
			if(pos)
			{
				ans1++;
				if(!query(1, l, r)) {ans2++; change(1, pos, pos);}
			}
		}
		cout << ans1 << " " << m-ans2 << endl;
	}
	return 0;
}

2024/10/30 19:12
加载中...