杭二学习Day4——比赛

背景:

爆炸了。

T1 \text{T1} T1

que \text{que} que

给出 a , b , c a,b,c a,b,c,问能构造多少种方案的多项式使得 f ( a ) = b , f ( b ) = c f(a)=b,f(b)=c f(a)=b,f(b)=c

sol \text{sol} sol

很容易想到一种做法。
我们发现 x x x的系数不为 0 0 0的上限是 min ⁡ ( log ⁡ a b , log ⁡ b c ) \min(\log_ab,\log_bc) min(logab,logbc)
考虑过后,我们发现这个并不大,直接搜索即可。
然后我因为没有判断无穷多解被卡到了 0 pts 0\text{pts} 0pts(多组数据)。

当然这不是正解。
首先我们就要判断无穷多解,即 a = b = c = 1 a=b=c=1 a=b=c=1
考虑 f ( b ) = c f(b)=c f(b)=c,考虑将 c c c b b b进制下表示出来,由于系数小于 b b b(不然就可以向前进 1 1 1了),不能构成 b b b进制下的进位,因此此时的第 k k k位(定义从右往左数分别为 0 , 1 , 2 , . . . 0,1,2,... 0,1,2,...位)就是 x k x^k xk项的系数。最后带入 f ( a ) = b f(a)=b f(a)=b中求解即可。
时间复杂度: Θ ( T log ⁡ b c ) \Theta(T\log_bc) Θ(Tlogbc) T T T表示数据组数)。

code \text{code} code

这么水,就不贴了吧。



T2 \text{T2} T2

que \text{que} que

给定 a , b , c , d a,b,c,d a,b,c,d,求 gcd ⁡ ( a F n + b F n + 1 , c F n + d F n + 1 ) \gcd(aF_n+bF_{n+1},cF_{n}+dF_{n+1}) gcd(aFn+bFn+1,cFn+dFn+1),其中 F i F_i Fi表示斐波那契数列第 i i i项。

sol \text{sol} sol

a ≤ c a≤c ac,若不满足,则 swap \text{swap} swap即可。
gcd ⁡ ( a F n + b F n + 1 , c F n + d F n + 1 ) \gcd(aF_n+bF_{n+1},cF_{n}+dF_{n+1}) gcd(aFn+bFn+1,cFn+dFn+1)

带入更相减损术(后面的那一个式子减去 ⌊ c a ⌋ \lfloor\frac{c}{a}\rfloor ac个前面的式子):
= gcd ⁡ ( a F n + b F n + 1 , ( c − a ⌊ c a ⌋ ) F n + ( d − b ⌊ c a ⌋ ) F n + 1 ) =\gcd(aF_n+bF_{n+1},(c-a\lfloor\frac{c}{a}\rfloor )F_n+(d-b\lfloor\frac{c}{a}\rfloor)F_{n+1}) =gcd(aFn+bFn+1,(caac)Fn+(dbac)Fn+1)

= gcd ⁡ ( a F n + b F n + 1 , ( c m o d    a ) F n + ( d − b ⌊ c a ⌋ ) F n + 1 ) =\gcd(aF_n+bF_{n+1},(c\mod a)F_n+(d-b\lfloor\frac{c}{a}\rfloor)F_{n+1}) =gcd(aFn+bFn+1,(cmoda)Fn+(dbac)Fn+1)

如此做 log ⁡ 2 c \log_2c log2c次化简后得到:
= gcd ⁡ ( a F n + b F n + 1 , c F n + 1 ) =\gcd(aF_n+bF_{n+1},cF_{n+1}) =gcd(aFn+bFn+1,cFn+1)

如果 a = 0 a=0 a=0 c = 0 c=0 c=0,特判掉即可。


先考虑求:
gcd ⁡ ( a F n + b F n + 1 , F n + 1 ) \gcd(aF_n+bF_{n+1},F_{n+1}) gcd(aFn+bFn+1,Fn+1)

考虑更相减损术,有:
= gcd ⁡ ( a F n , F n + 1 ) =\gcd(aF_n,F_{n+1}) =gcd(aFn,Fn+1)

由于 F n ⊥ F n + 1 F_{n}⊥F_{n+1} FnFn+1(互质),因此有:
= gcd ⁡ ( a , F n + 1 ) =\gcd(a,F_{n+1}) =gcd(a,Fn+1)

考虑辗转相除法,有:
= gcd ⁡ ( a , F n + 1 m o d    a ) =\gcd(a,F_{n+1}\mod a) =gcd(a,Fn+1moda)

用矩阵快速幂解决 F n + 1 m o d    a F_{n+1}\mod a Fn+1moda即可。


gcd ⁡ ( a F n + b F n + 1 , c F n + 1 ) \gcd(aF_n+bF_{n+1},cF_{n+1}) gcd(aFn+bFn+1,cFn+1)

提取 g = gcd ⁡ ( a F n + b F n + 1 , c F n + 1 ) g=\gcd(aF_n+bF_{n+1},cF_{n+1}) g=gcd(aFn+bFn+1,cFn+1),有:
= g ⋅ gcd ⁡ ( ( a F n + b F n + 1 ) / g , c ( F n + 1 / g ) ) =g\cdot\gcd\big((aF_n+bF_{n+1})/g,c(F_{n+1}/g)\big) =ggcd((aFn+bFn+1)/g,c(Fn+1/g))

可知此时 F n + 1 / g ⊥ ( a F n + b F n + 1 ) / g F_{n+1}/g⊥(aF_n+bF_{n+1})/g Fn+1/g(aFn+bFn+1)/g(两两互质),因此有:
= g ⋅ gcd ⁡ ( ( a F n + b F n + 1 ) / g , c ) =g\cdot\gcd\big((aF_n+bF_{n+1})/g,c\big) =ggcd((aFn+bFn+1)/g,c)

= gcd ⁡ ( ( a F n + b F n + 1 ) , c g ) =\gcd\big((aF_n+bF_{n+1}),cg\big) =gcd((aFn+bFn+1),cg)

= gcd ⁡ ( ( a F n + b F n + 1 ) , c g ) =\gcd\big((aF_n+bF_{n+1}),cg\big) =gcd((aFn+bFn+1),cg)

容易知道 c g &lt; a F n + b F n + 1 cg&lt;aF_n+bF_{n+1} cg<aFn+bFn+1,带入辗转相除法,有:
= gcd ⁡ ( ( a F n + b F n + 1 ) m o d &ThinSpace;&ThinSpace; ( c g ) , c g ) =\gcd\big((aF_n+bF_{n+1})\mod (cg),cg\big) =gcd((aFn+bFn+1)mod(cg),cg)

用矩阵快速幂解决 ( a F n + b F n + 1 ) m o d &ThinSpace;&ThinSpace; ( c g ) (aF_n+bF_{n+1})\mod (cg) (aFn+bFn+1)mod(cg)即可。

code \text{code} code

咕咕咕 ... \text{...} ...



T3 \text{T3} T3

que \text{que} que

原题传送门: luogu P4643 \text{luogu P4643} luogu P4643 [国家集训队]阿狸和桃子的游戏
一幅图, n n n个点,其中 { n ∣ n = 2 k , k ∈ N + } \{n|n=2k,k∈N_{+}\} {nn=2k,kN+}。每一轮你和对手轮流可以选择任意一个没有被染色的点染色,你染黑色,对手染白色。
每一个人的贡献是自己选的点的点权之和 + + +边权的贡献。对于边权贡献是,若连接一条边两个点颜色相同,则将这条边的权值加入对应颜色的人上。
可知最后你的贡献 − - 对手的贡献是固定的,求这个固定值。

sol \text{sol} sol

很妙啊。
定义 v a l val val表示这条边的权值。
将边权划入到点权中。
如果两边都是⿊点,对答案的贡献为 1 ∗ v a l 1*val 1val,可以看做两个⿊点分别为答案贡献了 1 2 ∗ v a l \frac{1}{2}*val 21val
如果两边都是⽩点,对答案的贡献为 − 1 ∗ v a l -1*val 1val,可以看做两个⽩点分别为答案贡献了 − 1 2 ∗ v a l -\frac{1}{2}*val 21val
如果⼀边是⽩点⼀边是⿊点,对答案的贡献为 0 0 0,可以看做⿊点为答案贡献了 1 2 ∗ v a l \frac{1}{2}*val 21val,⽩点为答案贡献了 − 1 2 ∗ v a l -\frac{1}{2}*val 21val
一种显然的博弈论知识是:对你新得到的点权降序,第奇数个的权值和为你的贡献;第偶数个的权值和为对手的贡献。

code \text{code} code

update \text{update} update 2019.8.8 2019.8.8 2019.8.8

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
	int n,m;
	double ans=0;
	double a[10010];
bool cmp(double x,double y)
{
	return x>y;
}
int main()
{
	int x,y;
	double z;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%lf",&a[i]);
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d %lf",&x,&y,&z);
		a[x]+=z/2,a[y]+=z/2;
	}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++)
		ans+=a[i]*((i&1)?1:-1);
	printf("%.0lf\n",ans);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值