求调玄关,蒟蒻已经调傻了
查看原帖
求调玄关,蒟蒻已经调傻了
1037502
luxiaomao楼主2024/11/20 21:52

rt,思路是用平衡树维护接下来会跳到哪个点,关于线段的比较方式已经按照题解改过了,但还是又WA又TLE,求大佬捉虫。

#include<bits/stdc++.h>
#define y1 kylAKIOI
#define y2 IOIAKjk
#define N 100005
using namespace std;

struct fun
{
	int l,r;
	double k,b;
};
bool operator < (fun x,fun y)
{
	if(x.r == y.r)return x.k*x.r+x.b > y.k*y.r+y.b;
	else if(x.r < y.r)
	{
		double maxx = x.k*x.r+x.b;
		double maxy = y.k*y.r+y.b;
		double newk = (maxy-maxx)/(y.r-x.r);
		return newk < y.k;
	}
	else return !(y<x);
}
const double eps = 1e-6;
bool operator == (fun x,fun y)
{
	return x.l == y.l && x.r == y.r && abs(x.k-y.k)<eps && abs(x.b-y.b)<eps;
}
bool operator > (fun x,fun y)
{
	return !(x<y || x==y);
}
fun get(int x1,int y1,int x2,int y2)
{
	double k,b;
	if(x1 == x2 && y1 == y2)
	{
		k = 0;
		b = y1;
	}
	else
	{
		k = (y2-y1)*1.0/(x2-x1);
		b = y1-k*x1;
	}
	fun ret;
	ret.l = x1,ret.r = x2,ret.k = k,ret.b = b;
	return ret;
}

int rt,tot;
struct node
{
	int fa,son[2],cnt,sz;
	fun v;
}t[N];
void clear(int u){t[u].fa = t[u].son[0] = t[u].son[1] = t[u].cnt = t[u].sz = t[u].v.k = t[u].v.b = t[u].v.l = t[u].v.r = 0;}
void upd(int u){t[u].sz = t[t[u].son[0]].sz + t[t[u].son[1]].sz + t[u].cnt;}
bool get(int u){return t[t[u].fa].son[1] == u;}
void rot(int u)
{
	int k = get(u),v = t[u].fa,w = t[v].fa;
	t[v].son[k] = t[u].son[k^1];
	if(t[u].son[k^1])t[t[u].son[k^1]].fa = v;
	t[u].son[k^1] = v;
	t[v].fa = u,t[u].fa = w;
	if(w)t[w].son[t[w].son[1] == v] = u;
	upd(v),upd(u);
}
void splay(int u)
{
	for(int v = t[u].fa;v = t[u].fa,v;rot(u))
		if(t[v].fa)rot(get(u) == get(v)?v:u);
	rt = u;
}
int build(fun x)
{
	t[++tot].v = x;
	t[tot].cnt = t[tot].sz = 1;
	return tot;
}
void ins(int las,int u,fun x)
{
	if(!u)
	{
		u = build(x);
//		printf("OK!!\n");
//		printf("OK!!we have inserted y=%lfx+%lf(%d<=x<%d)\n",x.k,x.b,x.l,x.r);
		if(!rt)rt = u;
		t[u].fa = las;
		if(las)t[las].son[x > t[las].v] = u,upd(las);
		splay(u);
		return;
	}
	if(x == t[u].v)
	{
		t[u].cnt++;
		upd(u);
		splay(u);
		return;
	}
	ins(u,t[u].son[x > t[u].v],x);
}
void fd(int u,fun x)
{
	if(!u)return;
	if(x < t[u].v)fd(t[u].son[0],x);
	else if(x == t[u].v)
	{
		splay(u);
		return;
	}
	else if(x > t[u].v)fd(t[u].son[1],x);
}
int pre()
{
	int u = t[rt].son[0];
	if(!u)return 0;
	while(t[u].son[1])u = t[u].son[1];
	splay(u);
	return u;
}
int nxt()
{
	int u = t[rt].son[1];
	if(!u)return 0;
	while(t[u].son[0])u = t[u].son[0];
	splay(u);
	return u;
}
void dfs(int u,int deep)
{
	if(!u)return;
	dfs(t[u].son[0],deep+1);
	for(int i = 1;i <= deep;i++)printf(" ");
	printf("y=%lfx+%lf (%d<=x<%d)",t[u].v.k,t[u].v.b,t[u].v.l,t[u].v.r);
	printf("  <%d(%d)%d>    (rt=%d)\n",t[u].son[0],u,t[u].son[1],rt);
	dfs(t[u].son[1],deep+1);
}
void del(fun x)
{
	fd(rt,x);
	int u = rt;
	if(t[u].cnt > 1)
	{
		t[u].cnt--;
		upd(u);
		return;
	}
	if(!t[u].son[0] && !t[u].son[1])
	{
		rt = 0;
		clear(u);
		return;
	}
	if(t[u].son[0] && !t[u].son[1])
	{
		rt = t[u].son[0];
		t[rt].fa = 0;
		clear(u);
		return;
	}
	if(!t[u].son[0] && t[u].son[1])
	{
		rt = t[u].son[1];
		t[rt].fa = 0;
		clear(u);
		return;
	}
	rt = pre();
	t[rt].son[1] = t[u].son[1];
	t[t[u].son[1]].fa = rt;
	upd(rt);
	clear(u);
}


int n,ans;
fun a[N];
bool cmp(fun x,fun y)
{
	return x.l < y.l;
}
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;

int main()
{
	scanf("%d",&n);
	for(int i = 1;i <= n;i++)
	{
		int x1,y1,x2,y2;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		a[i] = get(x1,y1,x2,y2);
	}
	sort(a+2,a+1+n,cmp);
	ans = 1;
	int nowx = a[1].r,nowy = a[1].k*a[1].r+a[1].b;
	int it = 2;
	while(1)
	{
		while(!q.empty() && q.top().first <= nowx)
		{
			del(a[q.top().second]);
			q.pop();
		}
		while(nowx >= a[it].l && it <= n)
		{
			ins(0,rt,a[it]);
			q.push(make_pair(a[it].r,it));
			it++;
		}
		ins(0,rt,get(nowx,nowy,nowx,nowy));
		int u = nxt();
		if(!u)break;
		del(get(nowx,nowy,nowx,nowy));
		nowx = t[u].v.r;
		nowy = t[u].v.k * t[u].v.r + t[u].v.b;
		ans++;
	}
	return printf("%d\n",ans),0x0;
}
2024/11/20 21:52
加载中...