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

做题记录 2

时间:2024-11-13 19:20:28浏览次数:1  
标签:le gcd 记录 int 合法 state 区间

好久以前的了。

我的题是 10

10

两棵根为 1 的树,一次可以删一个点、把所有儿子连到它的父亲,问最少操作次数使两棵树一样,\(n\le40\)

03

对序列 \(a\),定义一次变换为先让 \(\displaystyle s_k=\left(\sum_{i=k-\text{lowbit}(k)+1}^ka_i\right)\bmod 998\ 244\ 353\),然后 \(a_i\gets s_i\),问给出 \(k\) 次变换后的数组 \(b_i\),让你输出一个可行的原数组 \(a_i\),\(n\le2\cdot10^5,1\le k\le10^9,0\le b_i<998244353\).

04

给 \(n,m\),求 \((a,b)\) 个数,其中 \(a\in[1..n],b\in[1..m]\),且 \(b\cdot\gcd(a,b)\) 是 \(a+b\) 的倍数,\(n,m\le2\cdot10^6\).

05

二分图匹配,但是左边每个人连向的都是一段区间,\(\forall k\in[1..n_1]\),输出从右边点选任意长度为 \(k\) 的区间和左边所有人做匹配,匹配数能达到 \(k\) 的区间的个数,\(n_1,n_2\le2\cdot10^5\).

06

三维空间的墙角平铺有 \(n\times m\) 的立方体,每个立方体有一个颜色,目标是通过添加立方体来使每个颜色的立方体集合形成一个连通块,\(n,m,k\le50\),最多允许添加 \(4\cdot10^5\) 个立方体.

07

\(n(\le1000)\) 个数的回文数组 \(a(1\le a_i\le10^9)\),现给出它 \(\frac{n(n+1)}2-1\) 个子区间和,问还原数组 \(a\).


Solution

10

记两棵树为 \(S,T\)
操作性质:祖先关系不变
启示:若 \(S\) 中 \(i\) 是 \(j\) 的祖先 而在 \(T\) 中 \(i\) 不是 \(j\) 的祖先,那 \(i,j\) 必不能同时存在
建一个图,边 \((i,j)\) 表示 \(i,j\) 的祖先关系在两棵树中相同,我们需要找到其中的最大完全子图(最大团)
这就有很多方法了,std是这样:
\(f(state)\) 表示从 \(state\) 里面选点,选出团的最大大小
记忆化搜索,设 \(v\) 为 \(state\) 里的第一个点:

  • 选 \(v\):把 \(state\) AND一下 \(v\) 的所有邻居(不含 \(v\)),再返回 \(f(state)+1\)
  • 不选 \(v\):把 \(state\) 里 \(v\) 这一位变成 \(0\),再返回 \(f(state)\)
    边界:\(f(0)=0\);答案:\(f(2^n-1)\).
    他证明了这个复杂度是 \(O(n\cdot2^{0.5n})\),方法是分类讨论,但是我感觉不怎么对,反正 \(O(\)能过\()\).

03

Sol1:给的式子是个 \(\log\) 阶前缀和状物,所以最后每个位置必定是一个对 \(k\) 的 \(O(\log)\) 阶多项式,故暴力跑前 \(\log\) 次,然后对每个位置都插一遍就做完了,\(O(n\log n)\).
Sol2:由树状数组结构得 \(a_i\) 对 \(a_i\) 及它的祖先产生贡献,那设有两点 \(u,v\),且 \(u\) 在 \(v\) 的上面 \(d\) 层,做了 \(k\) 次,考虑 \(v\) 对 \(u\) 贡献了多少次,发现相当于对 \(\{1,0,0,0,\ldots\}\) 做 \(k\) 次前缀和,答案为 \(C_{d+k-1}^{k-1}\).于是我们从叶子往上依次减贡献,\(O(n\log n)\).

Code
#include <bits/stdc++.h>
using namespace std;
const int p = 998244353;
int Qpow(int x, int y = p - 2) {
	int res = 1;
	for (; y; y >>= 1, x = 1ll * x * x % p) if (y & 1) res = 1ll * res * x % p;
	return res;
}
int C(int n, int m) {
	int P = 1, Q = 1;
	for (int i = n; i >= n - m + 1; --i) P = 1ll * P * i % p;
	for (int i = 1; i <= m; ++i) Q = 1ll * Q * i % p;
	return (int)(1ll * P * Qpow(Q) % p);
}

void solve() {
	int n, k;
	cin >> n >> k;
	vector<int> a(n + 1), fa(n + 1), du(n + 1, 0);
	for (int i = 1; i <= n; ++i) cin >> a[i], fa[i] = i + (i & -i), (fa[i] > n) ? (fa[i] = 0) : (++du[fa[i]]);
	queue<int> q;
	for (int i = 1; i <= n; ++i) if (!du[i]) q.push(i);
	while (!q.empty()) {
		int u = q.front(), d = 1, v = u;
		q.pop();
		if (!--du[fa[u]]) q.push(fa[u]);
		while (fa[u]) (a[fa[u]] -= 1ll * C(d + k - 1, d) * a[v] % p - p) %= p, u = fa[u], ++d;
	}
	for (int i = 1; i <= n; ++i) cout << a[i] << " \n"[i == n];
}

int main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int tt;
	cin >> tt;
	while (tt--) solve();
	return 0;
}

04

  • \(a=pg,b=qg,\gcd(p,q)=1,g=\gcd(a,b)\)
  • \(b\cdot\gcd(a,b)=k(a+b)\),即 \(kg(p+q)=qg^2\),即 \(k(p+q)=gq\)
  • \(\gcd(p+q,q)=1\),故设 \(g=(p+q)r\)
  • 条件转化为 \(a=p(p+q)r,b=q(p+q)r,\gcd(p,q)=1\),发现 \(p\le\sqrt n,q\le\sqrt m\)
  • 枚举 \(p,q\),\((a,b)\) 的个数与 \(r\) 无关,\(O(\sqrt{nm})=O(n)\),因为 \(n,m\) 同阶.
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve() {
	ll ans = 0;
	int n, m;
	cin >> n >> m;
	for (int p = 1; p * p <= n; ++p)
		for (int q = 1; q * q <= m; ++q) {
			int a = p * (p + q), b = q * (p + q);
			if (gcd(p, q) == 1 && a <= n && b <= m) 
				ans += min(n / a, m / b);
		}
	cout << ans << "\n";
}

int main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int tt;
	cin >> tt;
	while (tt--) solve();
	return 0;
}

05

前置知识:Hall 定理
判断右边点单个区间 \([l,r]\),考虑 Hall 定理,设 \(N(S)\) 为右边点 \(S\) 对应的左边点集大小,\(S\) 合法当且仅当 \(|N(S)|\ge|S|\),那么 \([l,r]\) 合法当且仅当 \(\forall S\subseteq[l,r],S\) 合法.
猜测只用判断成一段区间的 \(S\),但是会被以下数据叉掉:

3
1 3
2 2
2 2

对于 \([1,3]\),只有 \(\{1,3\}\) 不合法.
于是考虑处理初始的左边点的线段,发现对于 \([a,b],[a,c](b\le c)\),把他们换成 \([a,b],[a+1,c]\) 不影响结果(\(a=b=c\) 时相当于删掉这条线段),因为对于 \(a\) 点,为了最优,他一定会选 \([a,b]\) 而非 \([a,c]\).
处理后每个人的左端点互不相同,此时找性质,发现:

  • 可以只判成一段区间的 \(S\),因为若一个不合法的 \(S\) 不是一段连续的区间,考虑将其补全成一段区间,此时他还是不合法,因为每补全一个数,\(|N(S)|\) 至多增加 \(1\),此时有只包含这个数的区间.
  • 看单调性,发现若 \([l,r]\) 不合法,\([l,r+1],[l-1,r]\) 也不合法,因为 \([l,r]\) 合法当且仅当 \(\forall S\subseteq[l,r],S\) 合法.
    于是可以双指针求,对每个 \(l\) 最大的 \(r\) 使 \([l,r]\) 合法,最后差分统计即可.
Code
// by:Joey_c / sto hunction orz
#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define reo(i,j,k) for(int i=j;i>=k;i--)
#define debug fprintf(stderr,"Running %s on line %d...\n",__FUNCTION__,__LINE__)
#define fi first
#define se second
#define pb emplace_back
#define mp make_pair
typedef long long ll;
constexpr int N=2e5+10;

int main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int n,m=0,nn;cin>>n,nn=n;vector<pair<int,int>>a(n+1);vector<int>buc[N];rep(i,1,n)cin>>a[i].fi>>a[i].se,m=max(m,a[i].se),buc[a[i].fi].pb(a[i].se);
	n=0;priority_queue<int,vector<int>,greater<int>>q;
	rep(i,1,m){
		for(int j:buc[i])q.push(j);while(!q.empty()&&q.top()<i)q.pop();if(!q.empty())a[++n]=mp(i,q.top()),q.pop();
	}
	vector<int>b(m+2,0),c(m+2,0),ans(max(m,nn)+2,0);rep(i,1,n)b[a[i].fi]=1,++c[a[i].se];
	for(int s=0,l=m,r=m;l;--l){
		s+=c[l];while(r>=l&&s<r-l+1)s-=b[r--];if(r<=m)++ans[r-l+1];
	}reo(i,max(m,nn),1)ans[i]+=ans[i+1];rep(i,1,nn)cout<<ans[i]<<"\n";
	return 0;
}

06

思路:每次我们只关心最上层的方块,先让每列之间都隔出一列空列,然后一层一层的使每个颜色连通.
题解,自己粗略算了一发,377500,足以通过.

07

记区间和数组为 \(s_i\),考虑如果知道所有区间和怎么做:

  • 做法一:考虑出现奇数次的 \(s_i\),一定是跨过中点且两边长度相等的,那我们把它们排序,设序列中点为 \(i,j(i\le j)\),我们得到 \([i,j],[i-1,j+1],[i-2,j+2],\ldots,[1,n]\) 的和,差分后可以还原数组 \(a\).
  • 做法二:考虑 \(s_i\) 的最大值和次大值,一定是 \([1,n],[1,n-1]\),那我们可以得到 \(a_1,a_n\),进而得到 \([2,n-1]\) 的和;将 \([1,n],[1,n-1],[2,n-1]\) 从集合里删去后,最大值一定是 \([1,n-2]\),那我们可以推出 \(a_2,a_{n-1}\),进而得到 \([1,n-2],[2,n-2],[3,n-2]\) 的和。注意到所有可能大于 \([1,n-3]\) 的区间和我们都知道,那把它们全都删掉后最大值即为 \([1,n-3]\),依次推下去可以还原数组 \(a\).
    现在考虑有一个元素缺失怎么做:
  • \(s_i\) 最大值出现 2 次:即缺失的是 \([1,n]\),我们采用做法一,可以得到 \(a_2,a_3,\ldots,a_{n-1}\),由于此时最大值为 \([1,n-1]\),也容易得到 \(a_1,a_n\).
  • \(s_i\) 最大值出现 1 次:直接采用做法二,只要 \([1,n]\) 不缺失就不影响做法二.
    时间:\(O(n^2\log n)\).

标签:le,gcd,记录,int,合法,state,区间
From: https://www.cnblogs.com/laijinyi/p/18544601

相关文章

  • 做题记录 3
    我:0808CF1955H塔防游戏,游戏有\(n\timesm\)的地图,地图上已经有\(k\)座塔,并给出敌人从\((1,1)\)移动到\((n,m)\)的路径,敌人每秒移动一格,恰好遍历完这个路径;一秒内若敌人在\((x,y)\),而一个塔\(i\)满足\((x-x_i)^2+(y-y_i)^2\ler_i^2\),则敌人收到\(p_i\)伤害;若敌人......
  • starrycan的pwn学习记录1
    一.Introducation0x01简介CTF0x02什么是pwn”Pwn”是一个黑客语法的俚语词,是指攻破设备或者系统。发音类似“砰”,对黑客而言这就是成功实施黑客攻击的声音--砰的一声,被“黑”的电脑或手机就被你操纵了。CTF中的pwnCTF中的PWN主要是针对于二进制漏洞挖掘与利用,通常情况下选......
  • AtCoder Beginner Contest 353 - VP 记录
    Preface这次比赛蛮简单的,就是黄题有点多,少了区分度。而且SigmaProblemAnotherSigmaProblemYetAnotherSigmaProblem是什么奇妙的题目名称?SigmaProblemAnotherSigmaProblemYetAnotherSigmaProblem\(\texttt{\scriptsizeYet\footnotesizeA......
  • fastadmin 数据记录行上添加操作按钮并设置权限
    1.一键curd以及配置菜单编写控制器方法-业务逻辑再次一键生成菜单-生成刚刚写审核通过方法的控制器。 2.自定义控制器中方法。3.查看角色组的权限,并授予该角色权限。4.前端修改index页面,因为需要权限所以需要加上一句话data-operate-log="{:$auth->check('......
  • CW 模拟赛 11.13 个人记录
    T1算法暴力暴力思路是显然的,观察到并查集可以\(\mathcal{O}(n\logn)\)的维护题目中求的信息对于\(50\%\)的数据显然可以通过耗时\(10\rm{min}\),正常正解暴力疑似就是正解?????代码这个题只要挂了我就趋势,但是看这样子来说应该是\(T1\)放了简单题不挂......
  • Educational Codeforces Round 157 (Rated for Div. 2) - VP 记录
    Preface啊啊啊为什么我老是被简单题卡啊!A.TreasureChestA题题面这么长吓我一跳。分类讨论,钥匙在前面可以拿了钥匙直接到箱子那里;箱子在前面就尽量把箱子往钥匙搬,让折回的距离尽量小。点击查看代码#include<cstdio>#include<algorithm>usingnamespacestd;intmain......
  • 在Odoo开发中,ref是一个非常重要的函数,用于在XML文件中引用其他数据的ID,帮助我们快速定
    在Odoo开发中,ref是一个非常重要的函数,用于在XML文件中引用其他数据的ID,帮助我们快速定位和调用系统中已经存在的记录。ref的全称是reference,可以通过该函数引用特定的视图、字段、模型等元素,从而在模块开发中实现跨文件、跨模块的引用。下面我会详细解释ref的作用,并提供丰富的示例......
  • AtCoder 板刷记录
    话说为啥这些场都没有G题的说[ABC200F]MinflipSummation显然的策略是把全部都是一个数的段变成全不都是另一个数,然后考虑进行dp设一个dp[i][0/1][0/1]表示一下前i个字符中奇偶性为j填的数是k时j的总和然后直接做就行了,需要矩阵快速幂加速一下[ABC201F]Insert......
  • 打靶记录-朋友自搭靶机
    信息收集nmap-sn192.168.161.0/24nmap-sT-p-192.168.161.131-oA./portsnmap-sU--top-ports20192.168.161.131,没有明确开放的udp端口nmap-sT-sC-sV-O192.168.161.131-p22,80,111,3306-oA./details,详细扫开放的端口nmap--script=vuln-p22,80,111,3306......
  • 「贪心」做题记录
    「贪心」做题记录P2672[NOIP2015普及组]推销员由于不会走多余的路,所以行走产生的疲劳值只和最远的被推销的住户有关。设\(f_X(i)\)表示总共选\(X\)家住户,且第\(i\)户是最远的被推销的住户的情况下,最大的疲劳值。显然可以贪心地在前\(i-1\)户中选择\(X-1\)户疲劳......