首页 > 其他分享 >AGC057C 做题记录

AGC057C 做题记录

时间:2024-05-11 10:22:07浏览次数:20  
标签:记录 trie ll 取反 maxn AGC057C 操作 define

题面看着很吓人!但是经过了一步步的思考,切完后再来看,其实也不过如此。

纪念一下独立切的铜牌构造题。

由于有 \(+1\) 操作,考虑反着建立 01-trie,即以最低位作为第一个分支。这样 \(+1\) 操作相当于对最右边的一条链上每个点执行左右儿子交换。

考虑 trie 树上每个叶子挂着对应数值在 \(A\) 中的位置,我们的目标状态为:每个叶子挂着的数等于对应数值。

不管是异或还是 \(+1\) 操作,都只能交换左右儿子,所以无解的判定是容易的:进行一次 DFS,判断当前点 \(u\) 与目标状态的 \(v\) 子树是否合法,每次判断 \(u\) 的子树中最左边的叶子在 \(v\) 的左子树还是右子树,然后递归判定。

这样一遍 DFS 我们还能顺便求出 \(t_u=0/1\) 表示为了到达目标状态,点 \(u\) 是否需要交换左右儿子。

为了方便表述,我们以“\(t_u\) 的改变”来代替点 \(u\) 交换左右儿子的操作。那么,我们的目标是把所有点的 \(t\) 变为 \(0\)。

我们现在有两种方法:

  • 异或一个数,使得同一层内的点 \(t\) 值全部取反,或全都不改变。

  • \(+1\),使得最右边一条链上所有点的 \(t\) 值全部取反。

注意到对于一条链,如果我们通过异或操作把它“旋转”到最右边,进行一次 \(+1\) 操作,再旋转回来,等价于我们可以令这条链上的 \(t\) 值全部取反。

所以我们思考操作若干条链来达成目标。

但是不一定有解。在操作之前,我们可以先异或一个值 \(v\),使得一些层的 \(t\) 值取反。

具体的,枚举最后一层(不是叶子,是叶子上面的一层)是否先提前取反,然后依次往上枚举每一层。

设 \(d_u\) 表示被链覆盖的次数的奇偶性,有 \(d_u = d_{lson(u)}\operatorname{xor} d_{rson(u)}\),合法的条件为 \(d_u\operatorname{xor} t_u = 0\)。

如果该层全部点都满足 \(d_u\operatorname{xor} t_u = 1\),那么先提前把这一层所有 \(t\) 取反。

然后这题就做完了,操作次数显然远远小于 \(10^6\)。

点击查看代码
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define fi first
#define se second
#define pir pair <ll, ll>
#define mkp make_pair
#define pb push_back
using namespace std;
const ll maxn = 3e5 + 10, mod = 1e9 + 7;
ll n, a[maxn], b[maxn], ans[maxn << 2], len;
ll trie[maxn * 18][2], tot = 1, t[maxn * 18], fa[maxn * 18];
vector <ll> vec[20];
void dfs(ll bit, ll u, ll v, ll uw, ll vw) {
	if(bit == n) {
		if(b[uw] != vw) {
			puts("No");
			exit(0);
		} return;
	}
	if(b[uw] & (1 << bit)) {
		dfs(bit + 1, trie[u][0], trie[v][1], uw, vw | (1 << bit));
		dfs(bit + 1, trie[u][1], trie[v][0], uw | (1 << bit), vw);
		t[u] = 1;
	} else {
		dfs(bit + 1, trie[u][0], trie[v][0], uw, vw);
		dfs(bit + 1, trie[u][1], trie[v][1], uw | (1 << bit), vw | (1 << bit));
	}
}
ll tag;
ll query(ll u) {
	ll val = 0;
	for(ll i = n - 2; ~i; i--) {
		val |= (trie[fa[u]][1 ^ ((tag >> i) & 1)] == u) << i;
		u = fa[u];
	} return val;
}
void add1() {
	ll p = 1;
	for(ll i = 0; i < n; i++) {
		swap(trie[p][0], trie[p][1]);
		p = trie[p][(tag >> i) & 1];
	}
}
ll msk, d[maxn * 18], ok;
int main() {
	scanf("%lld", &n); vec[0].pb(1);
	for(ll i = 0; i < (1 << n); i++) {
		scanf("%lld", a + i); b[a[i]] = i;
		ll p = 1;
		for(ll j = 0; j < n; j++) {
			ll c = (a[i] >> j) & 1;
			if(!trie[p][c]) {
				trie[p][c] = ++tot;
				vec[j + 1].pb(tot);
				fa[tot] = p;
			}
			p = trie[p][c];
		}
	}
	dfs(0, 1, 1, 0, 0);
	for(ll i = 0; i < 2; i++) {
		msk = (i << n - 1), ok = 1;
		for(ll j: vec[n - 1]) d[j] = t[j] ^ i;
		for(ll j = n - 2; ~j; j--) {
			ll x = 0, gd = 0;
			for(ll k: vec[j]) {
				d[k] = t[k] ^ x;
				if(d[k] ^ d[trie[k][0]] ^ d[trie[k][1]]) {
					if(gd) {
						ok = 0;
						break;
					}
					x = 1, d[k] ^= 1;
				}
				gd = 1;
			}
			msk |= (x << j);
			if(!ok) break;
		}
		if(!ok) continue;
		ans[++len] = tag = msk;
		for(ll j: vec[n - 1])
			if(d[j]) {
				ll val = query(j);
				val ^= (1 << n - 1) - 1;
				ans[++len] = val, tag ^= val;
				add1(), ans[++len] = -1;
			}
		ans[++len] = tag ^ msk;
		puts("Yes");
		printf("%lld\n", len);
		for(ll i = 1; i <= len; i++)
			printf("%lld ", ans[i]);
		return 0;
	}
	puts("No");
	return 0;
}

标签:记录,trie,ll,取反,maxn,AGC057C,操作,define
From: https://www.cnblogs.com/Sktn0089/p/18185905

相关文章

  • 记录一次微调大模型
    (chat)root@dsw-372547-675546dd46-gjcqb:/mnt/workspace/ChatGLM3/finetune_demo#pythonfinetune_hf.pyformatted_data//mnt/workspace/ChatGLM3/chatglm3-6bconfigs/lora.yamlyesSettingeos_tokenisnotsupported,usethedefaultone.Settingpad_tokeni......
  • AGC028E 做题记录
    好厉害!首先使用贪心策略,从左往右扫,能填\(0\)就填\(0\),问题变为判定性问题。首先我们先观察性质。性质:\(P\)中的前缀最大值一定有\(1\)的贡献,其他元素的贡献可以为\(0\),一定条件下可以为\(1\)。然后就不会了,个人只会\(O(n^2)\)的DP。考虑猜结论。结论:把\(P_{i......
  • 任天堂Switch硬件修复记录
    硬件修复记录;从软件世界里走出来,硬起来朗读全文Yourbrowserdoesnotsupporttheaudioelement.有什么用你可以了解到任天堂Switch的一些硬件知识。如果愿意,你也可以动手处理你自己手上的游戏机,还可以知道日常使用过程中的注意事项,防止/避免人为损坏,至少拉长这些硬件的......
  • 任天堂Switch黑屏救砖记录
    Switch黑屏救砖朗读全文Yourbrowserdoesnotsupporttheaudioelement.有什么用给救砖提供一些思路,相同的情况可以参考使用了解大气层虚拟系统的运作原理,自己动手在虚拟系统中安装新游戏:相关内容在线升级后导致黑屏的NS现状与诊断用新的大气层的短接器+注......
  • 任天堂Switch全部记录
    NSSWTICH大气层制作新的SD卡,解决部分大气层及固件问题。原先的SD卡(128G)快全部放满游戏了,需要新的内存卡用于存放新的游戏。有几张闲置的内存卡,可是容量最大只有64G,无法通过直接全部复制+粘贴的办法,来启用新的小内存卡,涉及制作新的NSSwitchSD卡有什么用switch大气层换sd......
  • c# 摄像头及保存视频记录
     usingSystem.IO;usingICameraDll.DirectX.Capture;Capturecapture;//摄像头录像操作Filtersfilters=newFilters();//Filter集合//函数intGetffshowIndex(){FilterCollectionvideoC......
  • 记录一次sqlMap的sql注入测试
    1、首先下载sqlMap测试工具 2、此前需要安装python环境执行pythonsqlmap.py-h ,则可以验证sqlmap命令是否生效3、get请求sql注入测试命令pythonsqlmap.py-uhttp://127.0.0.1:2000/data/serverConfigure/getDataByProject?projectId=1630016701175169121--risk=3--le......
  • Ant Design Blazor Table 组件的 自定义分页样式, 显示全部记录数,ShowTotal
    在AntDesignBlazor中,Table 组件的 ShowTotal 属性是一个泛型属性,它可以是两种类型之一:Func<PaginationTotalContext,string> 或 RenderFragment<PaginationTotalContext>。这个属性用于定义如何显示表格数据的总条数。OneOf<T1,T2> 是一个特殊的类型,它表示这个......
  • 2024.5 做题记录
    2023.5做题记录[Violet]天使玩偶显然发现我们需要在时间轴上进行cdq分治,然后统计答案。问题在于这个绝对值不好维护,需要进行转化。如果我们钦定这个点最近的点在它的左下方,那么绝对值就可以化为\(dis(A,B)=(A_x-B_x)+(A_y-B_y)=(A_x+A_y)-(B_x+B_y)\)。显然前面的括号是定......
  • 瑞萨问题排查记录
    P1当把RFD28F添加进项目时,报错如下:参考链接:https://www.sekorm.com/news/73776172.html栈溢出.textE0562330:Relocationsizeoverflow:"DefaultBuild\sample_control_codeflash.obj"-".text"-00000b(1)右键Subproject的CC-RH——LinkOptionsTab——S......