AtCoder Regular Contest 102D All Your Paths are Different Lengths 构造

原文链接https://www.cnblogs.com/zhouzhendong/p/ARC102D.html

题目传送门 - ARC102D

题意

  给定 $L$,请你构造一个节点个数为 $n$ ,边数为 $m$ 的图,边带权,满足以下条件:

  1. $n\leq 20$

  2. $m\leq 60$

  3. 如果有向边 $a\rightarrow b$ 存在,那么 $a<b$ 。

  4. 从 $1$ 走到 $n$ 总共有 $L$ 种不同的路径,这 $L$ 条路径的长度分别为 $0,1,\cdots , L-1$ 。

  $L\leq 10^6$

题解

  垃圾翻译告诉我 $n\geq 20$ 。于是我立马构造了一个 $40$ 个点的图来满足。在看样例的时候,我发现读错了题目。

  然后我就一直在想如何用 $2^k$ 的边权来构造。不知道为什么我只在想用这种边权构造。

  然后我扔掉这种做法想出了一个 AC 做法,5分钟敲完 AC 了。赛后,Funtionendless 给我讲了一下他口胡的做法,然而我发现和我之前想的假做法好像,说他是错的;然后最后我发现我…… 于是我又知道了一种做法。

  由于这两种做法的正确性都比较显然,所以不加解释。

  做法1:by me

build(x,L){//以x为当前子图的最小标号节点,构造一个具有 [0,L] 的路径长度的图
	if (L==0){
		AddEdge(x,n,0);
		return;
	}
	if (L==1){
		AddEdge(x,n,0);
		AddEdge(x,n,1);
		return;
	}
	y=NewNode();
	if (L mod 2==0)
		AddEdge(x,n,L);
	if (L mod 2==0)
		L=L div 2-1;
	else
		L=L div 2;
	AddEdge(x,y,0);
	AddEdge(x,y,L);
	build(y,L);
}

  

  做法2:by Funtionendless

int calc(int x,int i){
	return x&~((1<<(i+1))-1);
}
int GetD(int x,int i){
	return  x的i次二进制位;
}
n=20;
build(x,L){
	for (i = 0 to 18){
		AddEdge(i+1,i+2,Pow(2,i));
		AddEdge(i+1,i+2,0);
	}
	if (GetD(0))
		AddEdge(1,n,calc(L,0));
	for (i = 1 to 19)
		if (GetD(L,i)==1)
			AddEdge(i,n,calc(L,i));
}

  

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=105;
LL read(){
	LL x=0,f=1;
	char ch=getchar();
	while (!isdigit(ch)&&ch!=‘-‘)
		ch=getchar();
	if (ch==‘-‘)
		f=-1,ch=getchar();
	while (isdigit(ch))
		x=(x<<1)+(x<<3)+ch-48,ch=getchar();
	return x*f;
}
int n,m=0,L;
int A[N],B[N],C[N];
void push(int a,int b,int c){
	m++;
	A[m]=a;
	B[m]=b;
	C[m]=c;
}
int main(){
	L=read()-1;
	n=20;
	int cnt=1;
	while (L>=0){
		if (L==0){
			if (cnt<n)
				push(cnt,n,0);
			break;
		}
		if (L==1){
			push(cnt,n,0);
			push(cnt,n,1);
			break;
		}
		if (L%2==0)
			push(cnt,n,L);
		L=(L+1)/2;
		push(cnt,cnt+1,0);
		push(cnt,cnt+1,L);
		L--;
		cnt++;
	}
	printf("%d %d\n",n,m);
	for (int i=1;i<=m;i++)
		printf("%d %d %d\n",A[i],B[i],C[i]);
	return 0;
}

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/ARC102D.html

时间: 2024-10-05 03:27:55

AtCoder Regular Contest 102D All Your Paths are Different Lengths 构造的相关文章

AtCoder Regular Contest 098

AtCoder Regular Contest 098 C - Attention 题意 给定一个只包含"E","W"字符串,可以花一的花费使他们互相转换.选定一个位置,使位置左边的字符都变成E,右边都变成W所需要的最小花费. 分析 这题纯粹是签到题,做两个前缀和然后直接加就可以了. #include <iostream> #include <cmath> #include <cstring> #include <cstdi

AtCoder Regular Contest 095

AtCoder Regular Contest 095 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个A和Y个B最小花费使多少. 分析: 明显的发现肯定买性价比更高的方案,分情况讨论一下,如果\(a+b<=2*c\),那么明显的先买足c到A,B中较小的一个,然后再比较一下剩下的那个的单价和\(2*c\)的大小. A[ans=] -->|a+b<=2*c| B(A*a+B*b) A -->

AtCoder Regular Contest 094

AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几次操作将三个数变为相同的数. 分析: 可以发现如果三个数的奇偶性相同直接加就可以了,对于奇偶性不同的,先把奇偶性相同的两个数都+1,然后按照相同的处理就可以了.可以证明没有更好的方案. #include <bits/stdc++.h> using namespace std; int a,b,c,

AtCoder Regular Contest 103

AtCoder Regular Contest 103 一些吐槽 参加的第一场\(ARC\):一个模拟 + 三个构造 没见过比这更令人感动的题型设置了(简直就是针对我(TAT)) . 感觉全场就我一个人\(E\)题WA了四遍才过....... C-//// 题目大意: 网址 给定一个串\(S\),要求修改一些字符,使得串满足以下条件: \(S_i = S_{i+2}\) \(S_1 \neq S_2\) . 问最少需要修改多少个字符. 题解: 无脑统计一下奇数和偶数格的每种种类. 然后在最大值和

AtCoder Regular Contest 102 D - All Your Paths are Different Lengths

D - All Your Paths are Different Lengths 思路: 二进制构造 首先找到最大的t,使得2^t <= l 然后我们就能构造一种方法使得正好存在 0 到 2^t - 1 的路径 方法是:对于节点 i 到 i + 1,添加两条边,一条边权值是2^(i-1),一条边权值是0 对于剩下的2^t 到 l-1的路径,我们考虑倍增地求,每次添加一条节点 v 到 节点 n 的边,边的权值是 X ,新增的路径是X 到 X + 2^(v-1) - 1 第一次的X是 2^t,之后每

AtCoder Regular Contest 075 E - Meaningful Mean 树状数组求顺序对, 前缀和

题目链接: http://arc075.contest.atcoder.jp/tasks/arc075_c 题意: 给你一个序列和一个数k,求有多少对l,r,使得a[l]+a[l+1]+...+a[r]的算术平均数大于等于k 1≤N≤2×10^5 1≤K≤10^9 1≤ai≤10^9 思路: 首先对于所有数减去k,这样就不用除(r-l+1), 然后我们发现所求的就是有多少对l,r,使得sum[r]-sum[l-1] >= 0, sum是减去k之后的序列的前缀和 用树状数组对sum求有多少个顺序对

AtCoder Regular Contest 063 E:Integers on a Tree

题目传送门:https://arc063.contest.atcoder.jp/tasks/arc063_c 题目翻译 给你一个树,上面有\(k\)个点有权值,问你是否能把剩下的\(n-k\)个点全部填上权值,使得每条边链接的两个点权值相差\(1\),如果可以做到需要输出任意一组方案. 题解 我们考虑每条边权值为\(1\)或\(-1\),那么相当于黑白染色一样,所有点权值的奇偶性也都是确定的.如果与读入的\(k\)个点中某个点相冲突了就\(GG\).另外每个点的取值范围都可以转化成一段区间\([

AtCoder Regular Contest 062 E - AtCoDeerくんと立方体づくり / Building Cubes with AtCoDeer

题目传送门:https://arc062.contest.atcoder.jp/tasks/arc062_c 题目大意: 给你\(N\)块正方形木板,每块木板四角有四种颜色(可以相同),木板中央有编号,求选出6块不同的板子,围成的本质不同的合法立方体的个数.一个合法立方体,当且仅当木板有编号的一面在外面,且立方体顶点处的三个颜色相同.由于编号的存在,木板可以有4种形态.两个立方体本质相同,当且仅当存在一种空间旋转方式,使得两个立方体一模一样(包括编号方向) 没想到这题巨暴力--当我们确定对面的两

AtCoder Regular Contest 072 E:Alice in linear land

题目传送门:https://arc072.contest.atcoder.jp/tasks/arc072_c 题目翻译 给你一个数组\(D\),然后给你一个操作序列\(d\),每次操作可以将\(D\)变成\(min(D,|D-d[i]|)\).假如这一个操作序列执行完了之后你的\(D\)变成\(0\)了,那么就称这个操作序列是合法的.现在有\(Q\)个询问,每个询问由一个\(q[i]\)表示,问你假如你可以把\(d[i]\)变成任意正整数,你能否将这个操作序列变成不合法的.\(N,Q\leqsl