$\mathsf{\xcancel{跌袋}迭代做法求助}$
查看原帖
$\mathsf{\xcancel{跌袋}迭代做法求助}$
490879
徐崇瑜楼主2022/12/4 12:01
#define int int
#define intd "%d"
namespace PPP {
	#define tl template
	#define cu const unsigned
	template<cu __memory_size, cu __root_size> class manyset {
		private:
			struct node {
				int cnt, l, r, f;
				node() {
					cnt = l = r = f = 0;
				}
			} t[__memory_size];
			int root[__root_size], frt, rtf, min, max;
			int newnode() {
				t[++frt] = node();
				return frt;
			}
/*递归*/	void merge(int p, int q, int l, int r) {
				if(l == r)
					return t[p].cnt += t[q].cnt, t[q] = node(), void();
				int mid = l + r >> 1;
				if(t[p].l != 0 && t[q].l != 0)
					merge(t[p].l, t[q].l, l, mid);
				else if(t[q].l != 0)
					t[p].l = t[q].l, t[q].l = 0, t[t[p].l].f = p;
				if(t[p].r != 0 && t[q].r != 0)
					merge(t[p].r, t[q].r, mid + 1, r);
				else if(t[q].r != 0)
					t[p].r = t[q].r, t[q].r = 0, t[t[p].r].f = p;
				t[p].cnt = t[t[p].l].cnt + t[t[p].r].cnt, t[q] = node();
			}
		public:
			int newset() {
				root[++rtf] = newnode();
				return rtf;
			}
/*迭代*/	void modify(int p, int k, int v) {
				int now = root[p], l = min, r = max,
					mid = l + r >> 1;
				while(l != r) 
					if(k <= mid) {
						r = mid, mid = l + r >> 1;
						if(t[now].l == 0)
							t[now].l = newnode(), 
							t[t[now].l].f = now;
						now = t[now].l;
					} else {
						l = mid + 1, mid = l + r >> 1;
						if(t[now].r == 0)
							t[now].r = newnode(), 
							t[t[now].r].f = now;
						now = t[now].r;
					}
				t[now].cnt += v;
				while(now != root[p])
					t[t[now].f].cnt += v, now = t[now].f;
			}
/*迭代*/	int query(int p, int k) {
				if(k == 0)
					return 0;
				int now = root[p], l = min, r = max,
					mid = l + r >> 1, res = 0;
				while(l != r)
					if(k <= mid) {
						r = mid, mid = l + r >> 1;
						if(t[now].l == 0)
							return res;
						else
							now = t[now].l;
					} else {
						l = mid + 1, mid = l + r >> 1,
						res += t[t[now].l].cnt, 
						now = t[now].r;
						if(t[now].r == 0)
							return res;
					}
				res += t[now].cnt;
				return res;
			}
/*迭代*/	int find(int p, int k) {
				if(t[root[p]].cnt < k)
					return -1;
				int now = root[p], l = min, r = max,
					mid = l + r >> 1;
				while(l != r)
					if(k <= t[t[now].l].cnt)
						r = mid, mid = l + r >> 1,
						now = t[now].l;
					else
						l = mid + 1, mid = l + r >> 1,
						k -= t[t[now].l].cnt, 
						now = t[now].r;
				return l;
			}
/*迭代*/	void split(int p, int q, int k) {
				int now = root[p], newnow = root[q], 
					l = min, r = max, mid = l + r >> 1;
				while(l != r)
					if(k < mid) {
						r = mid, mid = l + r >> 1, 
						t[newnow].r = t[now].r, t[now].r = 0, t[t[newnow].r].f = newnow;
						if(t[now].l == 0)
							if(t[newnow].r == 0)
								break;
							else {
								t[newnow].cnt = t[t[newnow].l].cnt + t[t[newnow].r].cnt;
								break;
							}
						t[newnow].l = newnode(),
						t[t[newnow].l].f = newnow,
						newnow = t[newnow].l,
						now = t[now].l;
					} else if(k > mid) {
						l = mid + 1, mid = l + r >> 1;
						if(t[now].r == 0)
							break;
						t[newnow].r = newnode(),
						t[t[newnow].r].f = newnow,
						newnow = t[newnow].r,
						now = t[now].r;
					} else if(k == mid) {
						t[newnow].r = t[now].r, t[now].r = 0, t[t[newnow].r].f = newnow;
						break;
					}
				now = t[now].f, newnow = t[newnow].f;
				while(now != root[p])
					t[now].cnt = t[t[now].l].cnt + t[t[now].r].cnt,
					t[newnow].cnt = t[t[newnow].l].cnt + t[t[newnow].r].cnt,
					now = t[now].f, newnow = t[newnow].f;
			}
			void merge(int p, int q) {
				return merge(root[p], root[q], min, max);
			}
			manyset<__memory_size, __root_size>(int G, int H) {
				min = G, max = H;
				t[0] = node(), frt = rtf = 0, 
				root[++rtf] = newnode();
			}
	};
	#undef tl
	#undef cu
}
using namespace PPP;
#define scanf __builtin_scanf
#define printf __builtin_printf
int n, m;
manyset<4194304, 262144> f(1, 262144);
signed main() {
	scanf(intd intd, &n, &m);
	for(int i = 1, a; i <= n; i++)
		scanf(intd, &a), f.modify(1, i, a);
	while(m--) {
		int oper, p, q, x, y;
		scanf(intd, &oper);
		switch(oper) {
			case 0:
				scanf(intd intd intd, &p, &x, &y), q = f.newset(), 
				f.split(p, q, x - 1), f.split(q, 0, y), f.merge(p, 0);
				break;
			case 1:
				scanf(intd intd, &p, &q), f.merge(p, q);
				break;
			case 2:
				scanf(intd intd intd, &p, &x, &y), f.modify(p, y, x);
				break;
			case 3:
				scanf(intd intd intd, &p, &x, &y), 
				printf(intd " " intd "\n", f.query(p, y), f.query(p, x - 1));
				break;
			case 4:
				scanf(intd intd, &p, &x), 
				printf(intd "\n", f.find(p, x));
				break;
		}
	}
	return 0;
}
#undef int
#undef intd
#undef scanf
#undef printf

头文件吃了

如题,错误很可能在在 manyset::split()manyset::merge() 上,求查错 f 表示父节点

码风等勿喷

2022/12/4 12:01
加载中...