首页 > 其他分享 >洛谷 P7830 [CCO2021] Through Another Maze Darkly

洛谷 P7830 [CCO2021] Through Another Maze Darkly

时间:2023-10-05 22:55:19浏览次数:33  
标签:typedef 洛谷 pt int P7830 扩展 Darkly scd define

洛谷传送门

被联考创出 shit 了。

考虑一种极限情况:每个点指向父亲。那么这种情况我们会顺着欧拉序完整地把整棵树都走一遍。

但是初始的时候不一定每个点都指向父亲。发现我们走过 \(O(n^2)\) 步就能到达上面的极限情况。比较显然,因为每次扩展至少使一个点从不指向父亲变成指向父亲(称一次扩展为,不处于极限情况时,根结点走完一遍又回到自己的过程)。

考虑若一个点初始不指向父亲,那么第一次扩展到它时,它还没来得及扩展所有子结点就回到父亲了。但是第二次扩展可以扩展所有子结点。所以一个点至多需要访问 \(2\) 次。基于此考虑用一个队列维护还需要被访问的点,若遇到一个点没扩展完所有子结点就返回,就把它 push 进队列。

考虑如何回答询问。注意到每次扩展经过的结点编号序列,一定是最终欧拉序的子序列。于是我们把询问离线下来,扩展时把对应点的对应位置插入序列,查询就查一个下标第 \(k\) 大。可以使用树状数组维护。对于走到第 \(k\) 步时已经把整棵树扩展完的询问,因为它的周期是整棵树的欧拉序,所以也可以快速回答。

时间复杂度 \(O((n + q) \log n + q \log q)\)。

code
// Problem: P7830 [CCO2021] Through Another Maze Darkly
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P7830
// Memory Limit: 1 MB
// Time Limit: 8000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 22, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 22], *p1 = buf, *p2 = buf;
inline ll read() {
    char c = getchar();
    ll x = 0;
    for (; !isdigit(c); c = getchar()) ;
    for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x;
}

const int maxn = 1600100;

ll n, m, tt, fa[maxn], fd[maxn], ans[maxn], pt[maxn], a[maxn], tot, b[maxn], cnt;
bool vis[maxn];
pii qq[maxn];
vector<pii> G[maxn];
vector<int> vc[maxn];

void dfs(int u, int f) {
	for (pii &p : G[u]) {
		int v = p.fst;
		if (v == f) {
			p.scd = fd[u];
			continue;
		}
		p.scd = ++tt;
		fa[v] = u;
		fd[v] = tt;
		dfs(v, u);
	}
}

void dfs2(int u, int fa) {
	int t = pt[u], len = (int)G[u].size();
	while (1) {
		pt[u] = (pt[u] + 1) % len;
		if (pt[u] == t && u > 1) {
			break;
		}
		int v = G[u][pt[u]].fst;
		a[++tot] = v;
		b[tot] = G[u][pt[u]].scd;
		dfs2(v, u);
		a[++tot] = u;
		b[tot] = G[u][pt[u]].scd;
		if (pt[u] == t && u == 1) {
			break;
		}
	}
}

namespace BIT {
	int c[maxn];
	
	inline void update(int x, int d) {
		++cnt;
		for (int i = x; i <= n * 2 - 2; i += (i & (-i))) {
			c[i] += d;
		}
	}
	
	inline int kth(int k) {
		int p = 0;
		for (int i = __lg(n * 2 - 2); ~i; --i) {
			if (p + (1 << i) <= n * 2 - 2 && c[p + (1 << i)] < k) {
				p += (1 << i);
				k -= c[p];
			}
		}
		return p + 1;
	}
}

vector<int> nxt;

void dfs3(int u) {
	int len = (int)G[u].size();
	while (1) {
		pt[u] = (pt[u] + 1) % len;
		int v = G[u][pt[u]].fst, id = G[u][pt[u]].scd;
		if (vis[id]) {
			break;
		}
		if (v == fa[u]) {
			nxt.pb(u);
			break;
		}
		BIT::update(vc[id][0], 1);
		dfs3(v);
		vis[id] = 1;
		BIT::update(vc[id][1], 1);
	}
}

void solve() {
	n = read();
	m = read();
	for (int i = 1, k; i <= n; ++i) {
		k = read();
		while (k--) {
			G[i].pb(read(), 0);
		}
	}
	dfs(1, -1);
	for (int i = 2; i <= n; ++i) {
		for (int j = 0; j < (int)G[i].size(); ++j) {
			if (G[i][j].fst == fa[i]) {
				pt[i] = j;
				break;
			}
		}
	}
	dfs2(1, -1);
	for (int i = 1; i <= tot; ++i) {
		vc[b[i]].pb(i);
	}
	for (int i = 1; i <= m; ++i) {
		qq[i] = mkp(read(), i);
	}
	sort(qq + 1, qq + m + 1);
	mems(pt, 0);
	ll s = 0, j = 1;
	queue<int> q;
	q.push(1);
	while (cnt < tot) {
		ll lst = s;
		vector<int>().swap(nxt);
		while (q.size()) {
			int u = q.front();
			q.pop();
			dfs3(u);
		}
		for (int x : nxt) {
			q.push(x);
		}
		s += cnt;
		while (j <= m && qq[j].fst <= s) {
			ans[qq[j].scd] = a[BIT::kth(qq[j].fst - lst)];
			++j;
		}
	}
	while (j <= m) {
		ans[qq[j].scd] = a[(qq[j].fst - s - 1) % tot + 1];
		++j;
	}
	for (int i = 1; i <= m; ++i) {
		printf("%lld\n", ans[i]);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:typedef,洛谷,pt,int,P7830,扩展,Darkly,scd,define
From: https://www.cnblogs.com/zltzlt-blog/p/17744074.html

相关文章

  • 洛谷5324 删数
    首先给出结论:对于一个数列,某一个数字\(i\)的个数有\(cnt[i]\)个,那么此数字可以覆盖一个区间\([i-cnt[i]+1,i]\),遍历每一个数字并记录每个区间,最后答案就是没有被覆盖到的数字的个数证明:任意修改一个数字,会使一个\(cnt\)减一(这至多会产生一个没有被覆盖的数),另一个\(cnt\)加一(这至......
  • 洛谷 Power Tree 题解
    题目链接PowerTree分析将叶子节点按dfs序重标号后,每次控制操作可以转化为将子树内叶子节点所在区间加(或减)一个数不难可以想到将叶子区间进行差分每次对\(l\)到\(r\)的操作可以转化为将\(l\)上的数转移到\(r+1\)上每次操作后差分数组的和不变将所有点权变为\(0\)......
  • 洛谷P5303
    这一道题跟NOIP集训模拟赛1的D题非常像,当然D题的递推方程更复杂(磁盘里面有题解pdf)对于这一道题,我们设f[i][0]表示铺了i列而且全部用的完整的砖的方案数f[i][1]表示铺了i列,但是第i列缺了一个而且第i列的唯一的那一块砖头就是1X1其中一个f[i][2]表示铺了i列,但是第i列缺了一个而且......
  • 【题解】洛谷 P1003 [NOIP2011 提高组] 铺地毯
    原题链接解题思路如果直接按照题意开一个二维数组来模拟每个点最上面的地毯编号,会发现所占空间最坏情况下约为(2*105)2*4B=4*1010*4B=1.6*1011B≈149GB,程序完全无法运行。但实际上没有必要将每一个点的信息记录下来,只需要记录每一块地毯能覆盖哪些点,再依次判断哪那些地毯可以......
  • 洛谷5343总结
    这题我们很容易想出一个状态,设f[i][j]表示前i个长度划分长度为j的块的总方案然后我们自信的写出\(f[i][j]=f[i-1][j]+f[i][j-a[i]]\)但这其实是错的!这跟背包很想,+f[i][j-a[i]]这一项的本质是说这个长度为j的块的最后一段的长度是a[i],但其实最后一段的长度是不定的,所以我们可以写......
  • 洛谷 P5811 - [IOI2019] 景点划分
    小清新构造题。不妨假设\(a\leb\lec\)。显然我们会让大小为\(a,b\)的部分连通,这样肯定是不劣的。建出DFS树,考虑其重心\(r\),如果\(r\)的某个子树大小\(\gea\),我们在这个子树内挑一个大小为\(a\)的连通块,在抠掉这个子树之外的部分挑一个大小为\(b\)的连通块即可。......
  • 洛谷P3978 概率论
    首先考虑当节点数为n时,有多少个二叉树设\(f[i]\)表示节点为i时二叉树的个数,有\[f[n]=\sum_{i=1}^{n-1}f[i]f[n-1-i]\]注意这种递推式子也是卡特兰数的一种形式,所以为卡特兰数其实手写出前四项为1,2,5,14我们就要有足够的敏感度知道这是卡特兰数然后考虑叶子个数我们假设我们......
  • 【洛谷 P1305】新二叉树 题解(结构体数组+先序遍历+二叉树)
    新二叉树题目描述输入一串二叉树,输出其前序遍历。输入格式第一行为二叉树的节点数。()后面行,每一个字母为节点,后两个字母分别为其左右儿子。特别地,数据保证第一行读入的节点必为根节点。空节点用*表示输出格式二叉树的前序遍历。样例#1样例输入#16abcbdicj*d**i**j**......
  • 洛谷题解 | AT_abc321_c Primes on Interval
    目录题目翻译题目描述输入格式输出格式样例#1样例输入#1样例输出#1样例#2样例输入#2样例输出#2样例#3样例输入#3样例输出#3题目简化题目思路AC代码题目翻译【题目描述】你决定用素数定理来做一个调查.众所周知,素数又被称为质数,其含义就是除了数字一和本身之外不能......
  • 解题报告 洛谷P2155 [SDOI2008] 沙拉公主的困惑
    P2155[SDOI2008]沙拉公主的困惑题目题面非常的简洁,求\(\sum\limits_{i=1}^{n!}[i\perpm!]\)直接颓式子,\[\begin{aligned}ans&=\dfrac{n!}{m!}\cdot\varphi(m!)\\\\&=\dfrac{n!}{m!}*m!\prod\limits_{p\midm!}[\dfrac{p-1}{p}]\\&=n!\cdot\dfrac{\......