TLE 18/22 求调
查看原帖
TLE 18/22 求调
1132005
Contingency_Core楼主2024/6/30 13:19

总体思路 按X,Y排序,线段树按时间维护内最接近的点

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cstdio>
#include <map>
#include <vector>
#include <list>
#include <functional>
#include <stack>
#include <unordered_map>
#include <set>
#include <cctype>
#include <cstring>
#include <bitset>
#define m(a,b) make_pair(a,b)
#define F first
#define S second
#define ll long long
#define ull unsigned long long
#define us unsigned short
#define MAX(a,b) (a>b?a:b)
#define MIN(a,b) (a<b?a:b)
using namespace std;
const int N=200010,M=1e9*2;
int nt,n;
const pair<int,int> EMPTY=m(M,M);
struct aa
{
	pair<int,int> a,f;//a为这个点,f为目标点
	int st,et;//开始和结束时间
	char op;
} a[N];
aa *b[N],*bb[N];
struct node//线段树
{
	pair<int,int> change;
	int l,r,mid;
	bool empty;
} ste[N*4];
void rebuild(int i,int l,int r)
{
	ste[i].l=l;
	ste[i].r=r;
	ste[i].mid=(l+r)>>1;
	ste[i].change=EMPTY;
	ste[i].empty=0;
	if(l!=r)
	{
		rebuild(i<<1,l,ste[i].mid);
		rebuild((i<<1)+1,ste[i].mid+1,r);
	}
}
void spread(int &i)
{
	node &z1=ste[i<<1],&z2=ste[(i<<1)+1];
	if(ste[i].empty)
	{
		z1.change=z2.change=EMPTY;
		z1.empty=z2.empty=1;
		ste[i].empty=0;
	}
	else if(ste[i].change!=EMPTY)
	{
		z2.change=z1.change=ste[i].change;
		z2.empty=z1.empty=0;
		ste[i].change=EMPTY;
	}
}
void change(int i,int &l,int &r,pair<int,int> &x)
{
	if(ste[i].r<l||ste[i].l>r)
		return ;
	if(ste[i].l>=l&&ste[i].r<=r)
	{
		ste[i].change=x;
		ste[i].empty=0;
	}
	else
	{
		spread(i);
		change((i<<1),l,r,x);
		change((i<<1)+1,l,r,x);
	}
}
pair<int,int> ask(int i,int &k)
{
	if(ste[i].l==ste[i].r)
		return ste[i].change;
	if(ste[i].empty)
		return EMPTY;
	if(ste[i].change!=EMPTY)
		return ste[i].change;
	if(k>ste[i].mid)
		return ask((i<<1)+1,k);
	else
		return ask((i<<1),k);
}
bool cmpx(aa* &ai,aa* &bi)
{
	if(ai->a.first==bi->a.first)
	{
		if(ai->a.second==bi->a.second)
			return ai->op=='a';
		else
			return ai->a.second>bi->a.second;
	}
	else
		return ai->a.F>bi->a.F;
}
bool cmpy(aa* &ai,aa* &bi)
{
	if(ai->a.S==bi->a.S)
	{
		if(ai->a.F==bi->a.F)
			return ai->op=='a';
		else
			return ai->a.first>bi->a.first;
	}
	else
		return ai->a.S>bi->a.S;
}
bool cmpt(aa &a,aa &b)
{
	return a.st<b.st;
}
struct ct//时间哈希
{
	int t,i;
	bool s;
} bt[N];
bool cmpbt(ct &a,ct &b)
{
	return a.t<b.t;
}
int j[N];
int ji(int x)//记忆化搜索出发子树
{
	if(!j[x])
	{
		int i=1;
		while(ste[i].mid>=x)
			i<<=1;
		j[x]=i;
	}
	return j[x];
}
void fen(const int l,const int r)
{
	if(l==r)
		return ;
	int mid=(l+r)>>1,lt=1;
	for(int i=l;i<=r;i++)//时间哈希
	{
		bb[i]=b[i];
		bt[lt].s=1;
		bt[lt].i=i;
		bt[lt++].t=b[i]->st;
		if(b[i]->et!=nt)
		{
			bt[lt].s=0;
			bt[lt].i=i;
			bt[lt++].t=b[i]->et;
		}
	}
	int bsi=ji(lt);
	ste[bsi].empty=1;
	ste[bsi].change=EMPTY;
	sort(bt+1,bt+lt,cmpbt);
	for(int i=1;i<lt;i++)//时间哈希修改
	{
		if(bt[i].s)
			bb[bt[i].i]->st=i;
		else
			bb[bt[i].i]->et=i;
	}
	sort(bb+l,bb+mid+1,cmpx);
	sort(bb+mid+1,bb+r+1,cmpx);
	int x=l,y=mid+1;
	pair<int,int> cf;
	while(y<=r&&x<=mid)//双指针线段树
	{
		if(bb[x]->a.first>=bb[y]->a.first)
		{
			if(bb[x]->op=='a')
				change(bsi,bb[x]->st,bb[x]->et,bb[x]->a);
			x++;
		}
		else
		{
			if(bb[y]->op=='f')
			{
				cf=ask(bsi,bb[y]->st);
				if(cf.F<bb[y]->f.F||(cf.F==bb[y]->f.F&&cf.S<bb[y]->f.S))
					bb[y]->f=cf;
			}
			y++;
		}
	}
	while(y<=r)
	{
		if(bb[y]->op=='f')
		{
			cf=ask(bsi,bb[y]->st);
			if(cf.F<bb[y]->f.F||(cf.F==bb[y]->f.F&&cf.S<bb[y]->f.S))
				bb[y]->f=cf;
		}
		y++;
	}
	for(int i=1;i<lt;i++)//时间哈希改回
	{
		if(bt[i].s)
			b[bt[i].i]->st=bt[i].t;
		else
			b[bt[i].i]->et=bt[i].t;
	}
	fen(l,mid);
	fen(mid+1,r);
}
ull zll(pair<int,int> &x)
{
	return (ll)x.F*M+x.S;
} 
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out1.txt","w",stdout);
	unordered_map <ull,int> m;
	int t=1;
	ull c1;
	cin>>n;
	nt=n+3;
	getchar();
	for(int i=1;i<=n;i++)
	{
		a[i].op=getchar();
		switch(a[i].op)
		{
			case 'r':
				getchar(),getchar();
			case 'f':
				getchar();
			case 'a':
				getchar(),getchar(),getchar();
		}
		scanf("%d%d",&a[i].a.first,&a[i].a.second),getchar();
		a[i].f=EMPTY;
		a[i].et=nt;
		a[i].st=t;
		if(a[i].op=='a')//记录点
			m[zll(a[i].a)]=i;
		else if(a[i].op=='r')//找前一个点并修改结束时间
		{
			c1=zll(a[i].a);
			a[m[c1]].et=t;
			m.erase(m.find(c1));
			a[i]={};
			i--;
			n--;
		}
		else
		{
			a[i].a.first++;
			a[i].a.second++;
		}
		t++;
	}
	rebuild(1,1,nt);
	for(int i=1;i<=n;i++)
		b[i]=a+i;
	sort(b+1,b+n+1,cmpy);//用指针希望快一点
	fen(1,n);//CDQ
	for(int i=1;i<=n;++i)
	{
		if(a[i].op=='f')
		{
			if(a[i].f!=EMPTY)
				printf("%d %d\n",a[i].f.F,a[i].f.S);
			else
				putchar('-'),putchar('1'),putchar('\n');
		}
	}
	return 0;
}

抽象程序tle18 想尽力减少复杂度结果还不如不改

#include <iostream>//注释与上面程序类似(不想打了qwq)
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cstdio>
#include <map>
#include <vector>
#include <list>
#include <functional>
#include <stack>
#include <unordered_map>
#include <set>
#include <cctype>
#include <cstring>
#include <bitset>
#define m(a,b) make_pair(a,b)
#define F first
#define S second
#define ll long long
#define ull unsigned long long
#define us unsigned short
#define MAX(a,b) (a>b?a:b)
#define MIN(a,b) (a<b?a:b)
using namespace std;
const int N=200005,M=1e9*2;
int yi=1,nt,n;
const pair<int,int> EMPTY=m(M,M);
struct aa
{
	pair<int,int> a,f;
	int st,et;
	char op;
} a[N];
aa *b[N],*bb[N];
struct node
{
	pair<int,int> a,change;
	int l,r,mid;
	bool empty;
} ste[N*4];
void rebuild(int i,int l,int r)
{
	node &p=ste[i];
	p.l=l;
	p.r=r;
	p.mid=(l+r)>>1;
	p.a=p.change=EMPTY;
	if(l!=r)
	{
		rebuild(i*2,l,p.mid);
		rebuild(i*2+1,p.mid+1,r);
	}
}
void change(int i,int &l,int &r,pair<int,int> x);
void spread(int i)
{
	node &p=ste[i],&z1=ste[i*2],&z2=ste[i*2+1];
	if(p.empty)
	{
		z1.a=z2.a=z1.change=z2.change=EMPTY;
		z1.empty=z2.empty=1;
		p.empty=0;
	}
	else if(p.change!=EMPTY)
	{
		z2.a=z2.change=z1.a=z1.change=p.change;
		p.change=EMPTY;
	}
}
void change(int i,int &l,int &r,pair<int,int> x)
{
	node &p=ste[i],&z1=ste[i*2],&z2=ste[i*2+1];
	if(p.r<l||p.l>r)
		return ;
	if(p.l>=l&&p.r<=r)
	{
		p.a=p.change=x;
		p.empty=0;
	}
	else
	{
		spread(i);
		change(i*2,l,r,x);
		change(i*2+1,l,r,x);
		if(z1.a==z2.a)
			p.a=z1.a;
		else
			p.a=EMPTY;
	}
}
pair<int,int> ask(int i,int &k)
{
	if(ste[i].l==ste[i].r)
		return ste[i].a;
	if(ste[i].empty)
		return EMPTY;
	if(ste[i].a!=EMPTY)
		return ste[i].a;
	if(k>ste[i].mid)
		return ask(i*2+1,k);
	else
		return ask(i*2,k);
}
bool cmpx(aa* &ai,aa* &bi)
{
	if(ai->a.first==bi->a.first)
	{
		if(ai->a.second==bi->a.second)
			return ai->op=='a';
		else
			return ai->a.second>bi->a.second;
	}
	else
		return ai->a.F>bi->a.F;
}
bool cmpy(aa* &ai,aa* &bi)
{
	if(ai->a.S==bi->a.S)
	{
		if(ai->a.F==bi->a.F)
			return ai->op=='a';
		else
			return ai->a.first>bi->a.first;
	}
	else
		return ai->a.S>bi->a.S;
}
bool cmpt(aa &a,aa &b)
{
	return a.st<b.st;
}
void fen(const int l,const int r)
{
	if(l==r)
		return ;
	int mid=(l+r)>>1;
	//memcpy(bb+l,b+l,(r-l+1)*8);
	for(int i=l;i<=r;i++)
		bb[i]=b[i];
	sort(bb+l,bb+mid+1,cmpx);
	sort(bb+mid+1,bb+r+1,cmpx);
	int x=l,y=mid+1;
	pair<int,int> cf;
	while(y<=r&&x<=mid)
	{
		if(bb[x]->a.first>=bb[y]->a.first)
		{
			if(bb[x]->op=='a')
				change(1,bb[x]->st,bb[x]->et,bb[x]->a);
			x++;
		}
		else
		{
			if(bb[y]->op=='f')
			{
				cf=ask(1,bb[y]->st);
				if(cf.F<bb[y]->f.F||(cf.F==bb[y]->f.F&&cf.S<bb[y]->f.S))
					bb[y]->f=cf;
			}
			y++;
		}
	}
	while(y<=r)
	{
		if(bb[y]->op=='f')
		{
			cf=ask(1,bb[y]->st);
			if(cf.F<bb[y]->f.F||(cf.F==bb[y]->f.F&&cf.S<bb[y]->f.S))
				bb[y]->f=cf;
		}
		y++;
	}
	ste[1].empty=1;
	ste[1].a=ste[1].change=EMPTY;
	fen(l,mid);
	fen(mid+1,r);
}
ull zll(pair<int,int> &x)
{
	return (ll)x.F*M+x.S;
} 
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out1.txt","w",stdout);
	unordered_map <ull,int> m;
	int t=1;
	ull c1;
	cin>>n;
	nt=n+3;
	rebuild(1,1,n);
	getchar();
	for(int i=1;i<=n;i++)
	{
		a[i].op=getchar();
		switch(a[i].op)
		{
			case 'r':
				getchar(),getchar();
			case 'f':
				getchar();
			case 'a':
				getchar(),getchar(),getchar();
		}
		scanf("%d%d",&a[i].a.first,&a[i].a.second),getchar();
		a[i].f=EMPTY;
		a[i].et=nt+1;
		a[i].st=t;
		if(a[i].op=='a')
			m[zll(a[i].a)]=i;
		else if(a[i].op=='r')
		{
			c1=zll(a[i].a);
			a[m[c1]].et=t;
			m.erase(m.find(c1));
			a[i]={};
			i--;
			n--;
		}
		else
		{
			a[i].a.first++;
			a[i].a.second++;
		}
		t++;
	}
	for(int i=1;i<=n;i++)
		b[i]=a+i;
	sort(b+1,b+n+1,cmpy);
	fen(1,n);
	for(int i=1;i<=n;++i)
	{
		if(a[i].op=='f')
		{
			if(a[i].f!=EMPTY)
				printf("%d %d\n",a[i].f.F,a[i].f.S);
			else
				putchar('-'),putchar('1'),putchar('\n');
		}
	}
	return 0;
}

稍微正常的程序tle22 快读快写试过,但是感觉没用所以删了

2024/6/30 13:19
加载中...