社区讨论

求助:P3165已过但本题TLE on 6#

P4402[CERC2007] robotic sort 机械排序参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@m38d6hpb
此快照首次捕获于
2024/11/08 14:37
去年
此快照最后确认于
2025/11/04 15:08
4 个月前
查看原帖
试了好久都没找到原因,P3165过了,代码如下:
其他点都跑得很快唯独这个点T了,但是感觉不是死循环(大概在i=17800左右时间就跑到了900ms,而且在主函数的循环里超的时)
CPP
#include<bits/stdc++.h>
//#include<bits/extc++.h>
#define scanf __builtin_scanf
#define printf __builtin_printf
#define puts __builtin_puts
#define px first
#define py second
#define mkp make_pair
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int N=100005;
template<typename T>
struct Node{
	int ls,rs,len,p;
	T v,minn;
	bool rev;
	Node(): ls(0),rs(0),len(0),v(0,0),p(0),rev(0){}
};
Node<P> tr[N];
int tot;
mt19937 rnd(114514);
template<typename T>
class FHQ_Treap{
	int new_node(const T& x,const int& p){
		tr[++tot].v=x;
		tr[tot].p=p;
		tr[tot].len=1;
		tr[tot].minn=x;
		return tot;
	}
	void update(const int& i){
		tr[i].rev^=1;
		swap(tr[i].ls,tr[i].rs);
	}
	void push_down(const int& i){
		if(tr[i].rev){
			if(tr[i].ls) update(tr[i].ls);
			if(tr[i].rs) update(tr[i].rs);
			tr[i].rev=0;
		}
	}
	void push_up(const int& i){
		tr[i].len=tr[tr[i].ls].len+tr[tr[i].rs].len+1;
		tr[i].minn=min(min(tr[tr[i].ls].minn,tr[tr[i].rs].minn),tr[i].v);
	}
	int merge(int i,int j){
		if(!i||!j) return i|j;
		if(tr[i].p>tr[j].p) return push_down(i),tr[i].rs=merge(tr[i].rs,j),push_up(i),i;
		else return push_down(j),tr[j].ls=merge(i,tr[j].ls),push_up(j),j;
	}
	/*P split(int i,const T& x){
		if(!i) return mkp(0,0);
		P t;
		if(tr[i].v<=x) t=split(tr[i].rs,x),tr[i].rs=t.px,update(t.px=i);
		else t=split(tr[i].ls,x),tr[i].ls=t.py,update(t.py=i);
		return t;
	}*/
	P split(int i,const int& x){//分成下标 <x >=x 
		//cerr<<"split entry:"<<i<<" "<<x<<endl;
		if(!i) return mkp(0,0);
		push_down(i);
		P t;
		int l_len=tr[tr[i].ls].len+1;
		if(x>l_len) t=split(tr[i].rs,x-l_len),tr[i].rs=t.px,push_up(t.px=i);
		else t=split(tr[i].ls,x),tr[i].ls=t.py,push_up(t.py=i);
		return t;
	}
	int rt;
	int build(T a[],const int& l,const int& r,const int& prio){
		if(l>r) return 0;
		int mid=l+r>>1,i=new_node(a[mid],prio);
		tr[i].ls=build(a,l,mid-1,prio-1);
		tr[i].rs=build(a,mid+1,r,prio-(mid-l+1));
		push_up(i);
		return i;
	}
  public:
	FHQ_Treap(): rt(0){}
	FHQ_Treap(T a[],int n){rt=build(a,1,n,n);}
	void push_back(const T& x){
		rt=merge(rt,new_node(x,rnd()));
	}
	void insert(const int& i,const T& x){
		P t=split(rt,i);
		rt=merge(t.px,merge(new_node(x,rnd()),t.py));
	}
	void erase(const int& i){
		P l=split(rt,i),r=split(l.py,1);
		rt=merge(l.px,r.py);
	}
	T query(const int& i){
		P t=split(rt,i);
		int nw=t.py;
		while(tr[nw].ls) nw=tr[nw].ls;
		T ans=tr[nw].v;
		return rt=merge(t.px,t.py),ans;
	}
	void reverse(const int& il,const int& ir){
		P r=split(rt,ir+1),l=split(r.px,il);
		update(l.py);
		rt=merge(merge(l.px,l.py),r.py);
	}
	int query_mini(const int& il,const int& ir){
		P r=split(rt,ir+1),l=split(r.px,il);
		int ans=il,nw=l.py,l_len;
		//cerr<<tr[nw].minn<<endl;
		while(true){
			push_down(nw);
			l_len=tr[tr[nw].ls].len+1;
			if(tr[tr[nw].ls].minn==tr[nw].minn) nw=tr[nw].ls;
			else{
				ans+=l_len;
				if(tr[nw].minn==tr[nw].v) break;
				else nw=tr[nw].rs;
			}
		}
		return rt=merge(merge(l.px,l.py),r.py),ans-1;
	}
	/*int range_query(const int& il,const int& ir){
		P r=split(rt,ir+1),l=split(r.px,il);
		T ans=tr[l.py].minn;
		return rt=merge(merge(l.px,l.py),r.py),ans;
	}*/
	void print() const{
		cerr<<"rt="<<rt<<endl;
		for(int i=0;i<=tot;i++)
			cerr<<"Node "<<i<<":"<<tr[i].ls<<" "<<tr[i].rs<<" "<<tr[i].v.px<<" "<<
			tr[i].v.py<<" "<<tr[i].p<<" len:"<<tr[i].len<<" "<<tr[i].rev<<" "<<
			tr[i].minn.px<<" "<<tr[i].minn.py<<endl;
			//assert(tr[i].len==tr[tr[i].ls].len+tr[tr[i].rs].len+1);
	}
};
int n;
P b[N];
signed main(){
	tr[0].minn=mkp(INT_MAX,INT_MAX);
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&b[i].px),b[i].py=i;
	FHQ_Treap<P> a(b,n);
	/*a.print();
	for(int j=1;j<=i;j++) cerr<<a.query(j)<<" \n"[j==n];*/
	//a.print();
	for(int i=1,t;i<=n;i++){
		t=a.query_mini(i,n);
		a.reverse(i,t);
		printf("%d ",t);
		//for(int j=1;j<=n;j++) cerr<<a.query(j).px<<" \n"[j==n];
	}
	//for(int i=1;i<=n;i++) printf("%d ",a.query(i));
	return 0;
}
/*
6
2 3 2 3 2 3

1 3 5 5 5 6
*/

回复

1 条回复,欢迎继续交流。

正在加载回复...