莫队使用奇偶性排序优化后有什么方法卡掉吗
  • 板块学术版
  • 楼主B00m
  • 当前回复2
  • 已保存回复2
  • 发布时间2021/5/25 16:50
  • 上次更新2023/11/4 22:44:52
查看原帖
莫队使用奇偶性排序优化后有什么方法卡掉吗
156807
B00m楼主2021/5/25 16:50

如题

在ABC202三天后用树上莫队 nnn\sqrt{n} 过了E题 (2e5 @ 158ms) 之后有感而发

或者随便编个数据把我的代码卡掉吧 顺便看看我的代码还有哪里很糟糕 谢谢了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define int long long
#define inlint inline int
#define inloid inline void
#define EDGE(cu) for(int ed = nodes[cu].lastConn, to = edges[ed].to; ed; ed = edges[ed].next, to = edges[ed].to)
#define MAXN 200005
using namespace std;

namespace _MAIN{
	int n, m;
	inlint read(){
		register char c = getchar();
		int nega = 1, num = 0;
		for(;!isdigit(c);c = getchar()) if(c == '-') nega = -1;
		for(; isdigit(c);c = getchar()) num = num * 10 + c - '0';
		return nega * num;
	}
} using namespace _MAIN;

namespace _TREE{
	struct node{
		int lastConn, dep, F, heaLink, heaChild, siz, next, st, en;
	} nodes[MAXN];
	int euler[2 * MAXN], euCnt;
	struct edge{
		int next, to;
	} edges[2 * MAXN];
	int edCnt;
	void dfs1(int cu){
		nodes[cu].dep = nodes[nodes[cu].F].dep + 1;
		nodes[cu].siz = 1;
		euler[++euCnt] = cu;
		nodes[cu].st = euCnt;		
		EDGE(cu){
			if(to != nodes[cu].F){
				nodes[to].F = cu;
				dfs1(to);
				nodes[cu].siz += nodes[to].siz;
				if(nodes[to].siz > nodes[nodes[cu].heaChild].siz) nodes[cu].heaChild = to;
			}
		}
		euler[++euCnt] = cu;
		nodes[cu].en = euCnt;		
	}
	void dfs2(int cu, int ro){
		nodes[cu].heaLink = ro;
		if(nodes[cu].heaChild) dfs2(nodes[cu].heaChild, ro);
		EDGE(cu){
			if(to ^ nodes[cu].heaChild && to ^ nodes[cu].F) dfs2(to, to);
		}
	}
	inloid addEdge(int a, int b){
		edges[++edCnt].next = nodes[a].lastConn, edges[edCnt].to = b, nodes[a].lastConn = edCnt;
		edges[++edCnt].next = nodes[b].lastConn, edges[edCnt].to = a, nodes[b].lastConn = edCnt;
	}
	inlint LCA(int a, int b){
		while(nodes[a].heaLink != nodes[b].heaLink){
			if(nodes[nodes[a].heaLink].dep < nodes[nodes[b].heaLink].dep) swap(a, b);
			a = nodes[nodes[a].heaLink].F;
		}
		return nodes[a].dep > nodes[b].dep ? b : a;
	}	
} using namespace _TREE;

namespace _MO{
	int blockInd[2 * MAXN], sq;
	struct que{
		int l, r, id, dep, gotLCA;
		bool operator < (const que &b){
			return blockInd[l] ^ blockInd[b.l] ? l < b.l : blockInd[l] & 1 ? r < b.r : r > b.r;
		}
	} queries[MAXN];
	int cnt[MAXN], l = 1, r, ans[MAXN], euCnt[MAXN];
	inloid add(int x){
		++cnt[nodes[x].dep - 1]; 
	}
	inloid sub(int x){
		--cnt[nodes[x].dep - 1];
	}
	inloid edit(int x){
		(euCnt[x] ^= 1) ? add(x) : sub(x);
	}
	inloid solv(int num){
		while(l > queries[num].l) add(euler[--l]);
		while(r < queries[num].r) add(euler[++r]);
		while(l < queries[num].l) sub(euler[l++]);
		while(r > queries[num].r) sub(euler[r--]);
		ans[queries[num].id] = cnt[queries[num].dep] >> 1;
	}
	void init(){
        if(m) sq = n * 2 / sqrt(m * 2 / 3) + 1;
        for(int i = 1;i <= 2 * n;i++){
            blockInd[i] = i / sq + 1;
        }
        sort(queries + 1, queries + 1 + m);
    }
} using namespace _MO;

signed main(void){
	n = read();
	for(int i = 2; i <= n; i++){
		addEdge(i, read());
	}
	dfs1(1);
	dfs2(1, 1);
	m = read();
	for(int i = 1;i <= m;i++){
		int p = read();
		queries[i].l = nodes[p].st, queries[i].r = nodes[p].en, queries[i].dep = read(), queries[i].id = i;
	}
	init();
	for(int i = 1;i <= m;i++){
		solv(i);
	}
	for(int i = 1;i <= m;i++){
		cout << ans[i] << "\n";
	}
}
2021/5/25 16:50
加载中...