首页 > 其他分享 >省集Test3-D2 T2做题记录

省集Test3-D2 T2做题记录

时间:2024-05-29 19:59:30浏览次数:25  
标签:Test3 省集 ll 个数 define 做题 dis 边权 2k

link

一道比较深刻的题目。

考虑条件相当于:对于任意 \(1\) 的个数有限的 \(S\),其所有的长度为 \(2k+1\) 的子串,经过 \(p\) 的映射后 \(1\) 的个数不变。

  • 统计所有的长度固定的子串信息,我们有一个 trick:对于一个长为 \(2k+1\) 的二进制串 \(w\),设其前 \(2k\) 位和后 \(2k\) 位组成的串为 \(x,y\),我们连边 \(x\to y\)。

我们需要统计 \(1\) 的个数的信息,于是我们令 \(x\to y\) 的边权为:新产生的 \(S\) 的 \(1\) 的个数减去新产生的 \(S'\) 的 \(1\) 的个数。

问题变为我们可以在图上跑任意次,但必须满足所有边权和为 \(0\)。

根据鸽巢原理,我们总会找到两个相同的长为 \(2k+1\) 的子串。如果我们把周期循环下去,那么合法的条件是这两个子串之间走的环上的边权和为 \(0\)。

即:我们需要支持判断,是否满足任意环的边权和为 \(0\)。

我们可以建立权值为相反数的反向边,这样只需要判断图中是否存在负环,可以使用 SPFA。

接下来,我们先枚举 \(\text{lcp}(p,q)\),求出最大可能的 \(\text{lcp}\)。

然后,我们一位一位往后填写,并判断填写 \(0\) 是否合法。

对于后面的位,我们钦定边权和反向边边权都为可能的最大值,这样负环就没能在这上面占到便宜。

但是这样会超时:具体的,设 \(m = 2^{2k}\),那么时间复杂度为 \(O(m^3)\)。

  • Key Observe:注意到图是强连通的,且任何时候 \(dis_u \le 2k\)。当 \(dis_0<0\) 时就说明出现了负环,此时 SPFA 复杂度为 \(O(mk)\)。
点击查看代码
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define pir pair <ll, ll>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const ll maxn = 2e5 + 10;
ll t, k, dis[1 << 10], vis[1 << 10];
char p[maxn], q[maxn];
vector <pir> to[maxn];
queue <ll> que;
ll spfa() {
	for(ll i = 0; i < (1 << k); i++) dis[i] = 8e18, vis[i] = 0;
	dis[0] = 0;
	while(!que.empty()) que.pop();
	que.push(0);
	while(!que.empty()) {
		ll u = que.front(); que.pop();
		vis[u] = 0;
		for(pir e: to[u]) {
			ll v = e.fi, w = e.se;
			if(dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				if(dis[0] < 0) return 0;
				if(!vis[v]) {
					vis[v] = 1;
					que.push(v);
				}
			}
		}
	}
	return 1;
}
ll eq;
int main() {
	freopen("transform.in", "r", stdin);
	freopen("transform.out", "w", stdout);
	scanf("%lld", &t);
	while(t--) {
		scanf("%lld%s", &k, q);
		k <<= 1;
		eq = 1;
		ll pos = -5;
		for(ll i = -1; i < (1 << k + 1); i++) {
			if(i < (1 << k + 1) - 1 && q[i + 1] == '1') continue;
			for(ll u = 0; u < (1 << k); u++) to[u].clear();
			for(ll j = 0; j <= i; j++) {
				ll x = j >> 1, y = j & ((1 << k) - 1), t = (j & 1);
				to[x].pb(mkp(y, t - (q[j] - '0')));
				to[y].pb(mkp(x, (q[j] - '0') - t));
			}
			if(i < (1 << k + 1) - 1) {
				ll x = (i + 1) >> 1, y = (i + 1) & ((1 << k) - 1), t = i & 1 ^ 1;
				to[x].pb(mkp(y, t - 1));
				to[y].pb(mkp(x, 1 - t));
				for(ll j = i + 2; j < (1 << k + 1); j++) {
					x = j >> 1, y = j & ((1 << k) - 1), t = j & 1;
					to[x].pb(mkp(y, t));
					to[y].pb(mkp(x, 1 - t));
				}
			}
			if(spfa()) {
				pos = i;
			}
		}
		if(pos == -5) {
			puts("-1");
			continue;
		}
		if(pos == (1 << k + 1) - 1) {
			puts(q);
			continue;
		}
		for(ll i = 0; i <= pos; i++) p[i] = q[i];
		++pos;
		p[pos] = '1';
		for(ll i = pos + 1; i < (1 << k + 1); i++) {
			for(ll u = 0; u < (1 << k); u++) to[u].clear();
			ll x, y, t;
			for(ll j = 0; j < i; j++) {
				x = j >> 1, y = j & ((1 << k) - 1), t = (j & 1);
				to[x].pb(mkp(y, t - (p[j] - '0')));
				to[y].pb(mkp(x, (p[j] - '0') - t));
			}
			x = i >> 1, y = i & ((1 << k) - 1), t = i & 1;
			to[x].pb(mkp(y, t));
			to[y].pb(mkp(x, -t));
			for(ll j = i + 1; j < (1 << k + 1); j++) {
				x = j >> 1, y = j & ((1 << k) - 1), t = j & 1;
				to[x].pb(mkp(y, t));
				to[y].pb(mkp(x, 1 - t));
			}
			if(spfa()) {
				p[i] = '0';
			} else {
				p[i] = '1';
			}
		}
		p[1 << k + 1] = 0;
		puts(p);
	}
    return 0;
}

标签:Test3,省集,ll,个数,define,做题,dis,边权,2k
From: https://www.cnblogs.com/Sktn0089/p/18220911

相关文章

  • AGC061C 做题记录
    很具有启发性的题目。link我一开始没什么思路,选择了手动模拟来观察。这道题打破了我的按部就班的步骤:考虑直接创造一个条件,这样就能做到不重复。如果想到了这一点,我们其实就很容易想到这样一个条件:对于一个方案,\(\foralli\in[1,n],\(a_i,b_i)\)中没有其他人登记,那么\(i\)......
  • 推式子的做题记录
    「LOJ#3399」CommunicationNetwork首先列出式子,\(ans=\sum\limits_{T_2}|T_1\capT_2|2^{T_1\capT_2}\)注意到有\(f(S)=\sum\limits_{T\subseteqS}\sum\limits_{T'\subseteqT}(-1)^{T-T'}f(T')\)证明可考虑计算每个\(T'\)的贡献,由于\(T'\subse......
  • 数学部分做题记录
    I.[ARC152C]Pivot神仙题。II.CF1792EDivisorsandTableIII.CF1763DValidBitonicPermutationsIV.P6736「Wdsr-2」白泽教育注意到\(n\in\{1,2,3\}\)。\(n=1\):即\(a\uparrow^1x=a^x\equivb\pmodp\),这是一个平凡的BSGS问题。\(n=2\):我们有\[a\uparro......
  • NOI 2024 前做题纪要
    快退役了,最后一集了退役前还能做多少呢To-dolist#32024.5.24AGC025DChoosingPoints讲过关键性质是距离\(\sqrt{d}\)的点为二分图,于是每次选二分图较大的一边即可做到\(n^2\)。证明:考察\((x_1-x_2)^2+(y_1-y_2)^2=d\)奇偶性,\(d\)为奇数时\(x_1-x_2\)......
  • Ynoi 做题记录
    [Ynoi2011]初始化第一道通过的Ynoi题,虽然似乎大概也许并不太难。题目分析查询操作为求区间和,可以使用分块。看到这种修改操作满足“跳着加”性质的题目,可以尝试根号分治。那么如何进行根号分治呢?当\(x\ge\sqrt{n}\)时,需要修改的位置最多有\(\sqrt{n}\)个,故可以暴力......
  • 组合计数做题笔记
    \(\color{#FFC116}(1)\)CF1400DZigzags给出\(n\)个数\(a_1,a_2,\cdots,a_n\)。求问有多少个四元组\((i,j,k,l)\),使得这个四元组满足下列条件:\(1\leqi<j<k<l\leqn\);\(a_i=a_k\)并且\(a_j=a_l\)。\(a_i\len\le3000\)。显然可以枚举\(j,k\),所以此时......
  • ABC354 E - Remove Pairs 做题笔记
    ABC354E-RemovePairs做题笔记题目链接对于这种带有博弈论的dp,考虑这样设计状态:令\(f_s\in\{1,0\}\)表示“游戏局面”为\(s\)时,先手必胜还是必败。本题中,“游戏局面”可以表示为剩余卡牌的编号集合。又因为本题中\(N\)​很小,通过状压,可以直接用一个int表示游戏......
  • 动态规划做题笔记
    \(\color{blue}(1)\)P2606[ZJOI2010]排列计数求有多少\(1\simn\)的排列\(p\)满足\(\foralli\in[2,n],p_i>p_{\lfloori/2\rfloor}\),对\(m\)取模。\(n\le10^6\),\(m\le10^9\),\(m\)是一个质数。观察发现\(p_i>p_{\lfloori/2\rf......
  • 树做题笔记
    \(\color{#3498D8}(1)\)P4281[AHOI2008]紧急集合/聚会给定一棵\(n\)个节点的树。\(m\)次询问,每次给定\(a,b,c\),求一个节点\(u\)并使得三个点到\(u\)的距离和最小。求\(u\)和最小距离和。\(n,m\le5\times10^5\)。三个点\(a,b,c\)在树上的位置关系......
  • AGC057C 做题记录
    题面看着很吓人!但是经过了一步步的思考,切完后再来看,其实也不过如此。纪念一下独立切的铜牌构造题。由于有\(+1\)操作,考虑反着建立01-trie,即以最低位作为第一个分支。这样\(+1\)操作相当于对最右边的一条链上每个点执行左右儿子交换。考虑trie树上每个叶子挂着对应数值在......