平衡树被卡了?
查看原帖
平衡树被卡了?
380579
BMTXLRC楼主2021/8/26 14:22

49pts

如果被卡了的话想知道原理(

而且平衡树常数是不是很大(

求助(T 操作用 exgcd,没啥区别):

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5;
const ll mod=317847191;
ll n,k,x,root,cnt,nowx=1;
map<ll,bool> f;
struct treap{
	ll l,r,cnt=0;
	ll x,pri,size;
}a[N];
ll new_node(ll x){
	a[++cnt].x=x;
	a[cnt].pri=rand();
	a[cnt].cnt++;
	nowx=(nowx%mod*x%mod)%mod;
	return cnt;
}
void lturn(ll &now){
	ll tmp=a[now].r;
	a[now].r=a[tmp].l;
	a[tmp].l=now;
	now=tmp;
}
void rturn(ll &now){
	ll tmp=a[now].l;
	a[now].l=a[tmp].r;
	a[tmp].r=now;
	now=tmp;
}
void insert(ll &now,ll x){
    if(!now){
        now=new_node(x);  
        return;
    }
    if(x==a[now].x) a[now].cnt++,nowx=(nowx%mod*x%mod)%mod;      
    else{
        if(x<a[now].x){                         
            insert(a[now].l,x);
            if(a[now].pri<a[a[now].l].pri&&a[now].l) rturn(now);   
        }else{
            insert(a[now].r,x);                          
            if(a[now].pri<a[a[now].r].pri&&a[now].r) lturn(now);   
        }
    }     
}
ll Pow(ll a,ll k){
	ll ans=1;
	while(k){
		if(k&1) ans=(ans%mod*a%mod)%mod;
		a=(a%mod*a%mod)%mod;
		k>>=1;
	}
	return ans;
}
ll exgcd(ll a,ll b,ll &c,ll &k){
	if(!b){
		c=1,k=0;
		return a;
	}
	ll p=exgcd(b,a%b,c,k);
	ll q=c;
	c=k,k=q-a/b*k;
	return p;
}
void for_ans(ll p,ll mod,ll nowx,ll &c,ll &k){
	ll d=exgcd(p,mod,c,k);
	ll u=nowx/d;
	c=(c%mod*u%mod)%mod;
	k=(k%mod*u%mod)%mod;
	c=(c+mod)%mod;
}
void real_delete(ll &now){
	ll c=0,k=0;
	ll p=Pow(a[now].x,a[now].cnt);
	for_ans(p,mod,nowx,c,k);
	nowx=c,a[now].cnt=0,now=0;
}
void remove(ll &now,ll x){
    if(!now) return;   
    if(x==a[now].x){
        if(a[now].l||a[now].r){                                
            if(!a[now].r||a[a[now].l].pri>a[a[now].r].pri){     
                rturn(now);                               
                remove(a[now].r,x);
            }else{
                lturn(now);                 
                remove(a[now].l,x);
            }
        }else real_delete(now);                                     
        return;
    }
    if(x<a[now].x) remove(a[now].l,x);       
    else remove(a[now].r,x);                                    
}
ll find_max(ll now){
	if(a[now].r) return find_max(a[now].r);
	else return a[now].x;
}
ll find_min(ll now){
	if(a[now].l) return find_min(a[now].l);
	else return a[now].x;
}
int main(){
	scanf("%lld %lld",&n,&k);
	for(register int i=1;i<=n;i++){
		scanf("%lld",&x);
		insert(root,x);
	}
	for(register int i=1;i<=k;i++){
		char op=getchar();
		while(op>'Z'||op<'A') op=getchar();
		if(op=='M'){
			ll maxn=find_max(root);
			ll minn=find_min(root);
			printf("%lld\n",Pow(maxn,minn));
		}
		if(op=='D'){
			ll x;
			scanf("%lld",&x);
			if(f[x]) continue;
			f[x]=true;
			remove(root,x);
		}
		if(op=='B') printf("%lld\n",find_max(root));
		if(op=='S') printf("%lld\n",find_min(root));
		if(op=='T') printf("%lld\n",nowx);
		//M D B S T 可见出题人多么讨厌二叉搜索树( 
	}
}
2021/8/26 14:22
加载中...