TLE 80 pts 求助
查看原帖
TLE 80 pts 求助
399286
苏联小渣楼主2022/12/19 09:07

RT,思路是手写链表,fir 是每个链表头的编号,ed 是每个链表尾的编号,对每个链表维护一棵线段树。操作 1 直接在链表和线段树上加一个数,操作 2 删去一个数,操作 3 开一个新的根节点,并且一个个线段树合并,但是为了不对这些原来的线段树修改,遇到原有的结点就新开一个和它一样的结点,然后找众数就每次在线段树上找出现次数 >1/2>1/2 的那边递归下去。操作 4 就直接合并,最后四个点 TLE。

#include <bits/stdc++.h>
using namespace std;
#define N 2000000
#define begnote 1e9
#define endnote 1e9+1
#define emptynote 1e9+2
int n, m, q, op, x, y, z, cnt, tmp, rec, t[N], sz[N], fir[N], ed[N];
inline int read(){
	int s=0, w=1; char ch=getchar();
	while (ch<'0'||ch>'9'){if(ch=='-') w=-1; ch=getchar();}
	while (ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}
	return s*w;
}
struct List{
	int x, fr, nx;
}l[N];
struct segment{
	int l, r, vis;
	long long s;
}d[N<<5];
void modify(int &p, int l, int r, int x, int y){
	if (!p) p=++cnt, d[p].vis = 1;
	d[p].s += y;
	if (l == r) return ;
	int mid = l + r >> 1;
	if (x <= mid) modify(d[p].l, l, mid, x, y);
	else modify(d[p].r, mid+1, r, x, y);
}
int hb(int X, int Y, int l, int r, int tg){
	if (d[X].vis && tg){
		cnt ++;
		d[cnt] = d[X];
		X = cnt;
	}
	if (!X){
		if (d[Y].vis && tg){
			cnt ++;
			d[cnt] = d[Y];
			d[cnt].vis = 0;
			return cnt;
		}
		return Y;
	}
	if (!Y) return X;
	if (l == r){
		d[X].s += d[Y].s;
		return X;
	}
	int mid = l + r >> 1;
	d[X].l = hb(d[X].l, d[Y].l, l, mid, tg);
	d[X].r = hb(d[X].r, d[Y].r, mid+1, r, tg);
	d[X].s = d[d[X].l].s + d[d[X].r].s;
	return X;
}
int query(int p, int l, int r, long long lim){
	if (l == r) return l;
	int mid = l + r >> 1;
	if (d[d[p].l].s > lim) return query(d[p].l, l, mid, lim);
	if (d[d[p].r].s > lim) return query(d[p].r, mid+1, r, lim);
	return -1;
}
int main(){
	n=read(), q=read();
	for (int i=1; i<=n; i++){
		sz[i] = read();
		fir[i] = m + 1;
		for (int j=1; j<=sz[i]; j++){
			m ++;
			scanf ("%d", &l[m].x);
			modify(t[i], 1, N, l[m].x, 1);
			if (j > 1) l[m].fr = m-1;
			else l[m].fr = begnote;
			if (j < sz[i]) l[m].nx = m+1;
			else l[m].nx = endnote;
		}
		ed[i] = m;
		if (fir[i] == ed[i] + 1){
			fir[i] = ed[i] = emptynote;
		}
	}
	for (int i=1; i<=q; i++){
		op=read(), x=read();
		if (op == 1){
			m ++;
			l[m].x=read();
			sz[x] ++;
			if (fir[x] == emptynote){
				fir[x] = ed[x] = m;
				l[m].fr = begnote, l[m].nx = endnote;
			}
			else{
				l[m].fr = ed[x], l[m].nx = endnote;
				l[ed[x]].nx = m;
			}
			ed[x] = m;
			modify(t[x], 1, N, l[m].x, 1);
		}
		else if (op == 2){
			sz[x] --;
			modify(t[x], 1, N, l[ed[x]].x, -1);
			if (!sz[x]){
				fir[x] = ed[x] = emptynote;
			}
			else{
				ed[x] = l[ed[x]].fr;
				l[ed[x]].nx = endnote;
			}
		}
		else if (op == 3){
			tmp = ++cnt;
			long long tot = 0;
			for (int j=1; j<=x; j++){
				y=read();
				tmp = hb(tmp, t[y], 1, N, 1);
				tot += (long long)sz[y];
			}
			printf ("%d\n", query(tmp, 1, N, tot/2));
		}
		else{
			y=read(), z=read();
			hb(t[x], t[y], 1, N, 0);
			t[z] = t[x];
			sz[z] = sz[x] + sz[y], fir[z] = fir[x], ed[z] = ed[y];
			if (!sz[z]) continue;
			else if (sz[z] && !sz[y]){
				ed[z] = ed[x];
			}
			else if (sz[z] && !sz[x]){
				fir[z] = fir[y];
			}
			else{
				l[ed[x]].nx = fir[y];
				l[fir[y]].fr = ed[x];
			}
		}
	}
	return 0;
}
2022/12/19 09:07
加载中...