TJOI 2019 简要题解

[TJOI2019]唱、跳、rap和篮球
暴力枚举有多少个不满足条件的,有 i i i 个不满足的情况相当于在 n − 3 ∗ i n-3*i n3i 个里面选 i i i
其它的随便填,大力容斥, N T T NTT NTT即可
a n s = ∑ i = 0 n / 4 ( − 1 ) i ( n − 3 ∗ i i ) ( n − i ∗ 4 ) ! ∑ x 1 + x 2 + x 3 + x 4 = n − 4 ∗ i 1 x 1 ! 1 x 2 ! 1 x 3 ! 1 x 4 ! ans=\sum_{i=0}^{n/4}(-1)^i\binom{n-3*i}{i}(n-i*4)!\sum_{x_1+x_2+x_3+x_4=n-4*i}\frac{1}{x_1!}\frac{1}{x_2!}\frac{1}{x_3!}\frac{1}{x_4!} ans=i=0n/4(1)i(in3i)(ni4)!x1+x2+x3+x4=n4ix1!1x2!1x3!1x4!1
[TJOI2019]甲苯先生的滚榜
可以直接平衡树,每次修改就暴力删除再添加
也可以用树状数组维护严格小于它的个数,在对每个点动态开点一棵线段树维护第二维大于它的
[TJOI2019]甲苯先生的字符串
f i , j = ∑ k f i − 1 , k [ c a n ( k j ) ] f_{i,j}=\sum_k f_{i-1,k}[can(kj)] fi,j=kfi1,k[can(kj)]
a i , j a_{i,j} ai,j 表示字符 i , j i,j i,j 能不能放在一起,然后就是一个裸的矩阵乘
[TJOI2019]大中锋的游乐场
建好分层图后就是裸的最短路
[TJOI2019]甲苯先生和大中锋的字符串
考虑到一个串的出现次数就是 ∣ R i g h t ∣ |Right| Right,而该节点包涵的串的长度为 ( l e n [ l i n k [ i ] ] , l e n [ i ] ] (len[link[i]],len[i]] (len[link[i]],len[i]]
差分打个标记即可
[TJOI2019]甲苯先生的线段树
先考虑第一问, l c a lca lca 就是两点的 l c p lcp lcp
然后考虑求一个点到根的和,对于每一位求一下就是 2 ∗ x − p o p c n t ( x ) 2*x - popcnt(x) 2xpopcnt(x)
然后差分就是答案
第二问,考虑凭借运气枚举一些东西得到答案
如果直觉够准的话,你开始枚举一个点两端的长度
对于一个点,如果它左边长度为 a a a,右边长度为 b b b,那么 l c a lca lca 的贡献就是
l + 2 l + . . . + 2 a l = ( 2 a + 1 − 1 ) l l+2l+...+2^al=(2^{a+1}-1)l l+2l+...+2al=(2a+11)l,所以就是 ( 2 a + 1 + 2 b + 1 − 3 ) l (2^{a+1}+2^{b+1}-3)l (2a+1+2b+13)l
如果全部走左边,最小贡献为全部往右走,贡献为 1 + 2 + . . . + 2 b − 1 = 2 b − 1 1+2+...+2^{b-1}=2^b-1 1+2+...+2b1=2b1
最大贡献为 2 b + 1 + 2 a − a − b − 3 2^{b+1}+2^a-a-b-3 2b+1+2aab3
增量的最大值 2 b + 1 + 2 a − a − b − 3 2^{b+1}+2^a-a-b-3 2b+1+2aab3 都比 ( 2 a + 1 + 2 b + 1 − 3 ) (2^{a+1}+2^{b+1}-3) (2a+1+2b+13)
也就是一个 l c a lca lca 加上增量的最大值都比另一个 l c a lca lca 的最小值小
于是 l c a lca lca 可以定下来,为 s 2 a + 1 + 2 b + 1 − 3 \frac{s}{2^{a+1}+2^{b+1}-3} 2a+1+2b+13s
然后令 k = s % ( 2 a + 1 + 2 b + 1 − 3 ) k=s\%({2^{a+1}+2^{b+1}-3}) k=s%(2a+1+2b+13)
要使 a + b − c n t ( a ) − c n t ( b ) = k a+b-cnt(a)-cnt(b)=k a+bcnt(a)cnt(b)=k
枚举 c n t ( a ) + c n t ( b ) cnt(a)+cnt(b) cnt(a)+cnt(b)
也就是选两个二进制数使其和为 k, p o p c n t popcnt popcnt 之和为一个定值的方案数
方案数可以用数位dp 搞出来
f i , j , 0 / 1 f_{i,j,0/1} fi,j,0/1 表示到第 i 位,填了 j 个1,有没有进位到 i+1 的方案数
枚举当前 a a a填1, b b b 填1,都填,都不填转移就可以了
虽然很不好想,但是这种化简问题的方法可以学习
通过一步步转换,我们竟然将答案转换成了使 a + b = x a+b=x a+b=x 的方案数
值得学习!

#include<bits/stdc++.h>
#define N 55
using namespace std;
typedef long long ll;
ll read(){
	ll cnt = 0, f = 1; char ch = 0;
	while(!isdigit(ch)){ ch = getchar(); if(ch=='-') f = -1; } 
	while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();
	return cnt * f;
}
int T, d, typ; ll s, t;
ll dp[2][N][N<<1];
ll solve(ll sum, ll cnt, ll b1, ll b2){
	ll mxb = 1; while((1ll << mxb) <= sum) ++mxb;
	for(int i = 0; i <= cnt; i++) dp[0][0][i] = dp[1][0][i] = 0;
	dp[0][0][0] = 1;
	for(int b = 1; b < mxb; b++){
		sum >>= 1;
		for(int c = 0; c <= cnt; c++){
			dp[0][b][c] = dp[sum&1][b-1][c];
			dp[1][b][c] = 0;
			if(c && b < b1) dp[~sum&1][b][c] += dp[~sum&1][b-1][c-1];
			if(c && b < b2) dp[~sum&1][b][c] += dp[~sum&1][b-1][c-1];
			if(c && b < b1 && b < b2) dp[1][b][c] += dp[sum&1][b-1][c-2];
		}
	} return dp[0][mxb-1][cnt];
}
ll lca(ll x, ll y){ while(x^y){ if(x<y) swap(x,y); x >>= 1;} return x;}
ll pc(ll x){ ll ret = 0; while(x) x -= x&-x, ++ret; return ret;}
ll calc(ll x){ return (x << 1) - pc(x);}
int main(){
	T = read();
	while(T--){
		d = read(), s = read(), t = read(), typ = read();
		ll p = lca(s, t); ll sum = calc(s) + calc(t) - calc(p) - calc(p >> 1);
		if(typ == 1){ cout << sum << '\n'; continue;}
		ll ans = 0;
		for(int i = 0; i < d; i++){
			for(int j = 0; j < d; j++){
				ll ss = (1ll << i + 1) + (1ll << j + 1) - 3; if(sum < ss) break;
				ll pos = sum / ss; int l = 0; while(pos){ pos >>= 1; ++l; }
				if(l + i > d || l + j > d) continue;
				ll k = sum % ss - (1ll << j) + 1;
				if(k < 0) continue;
				for(int t = k&1; t <= i+j; t+=2)
					ans += solve(k + t, t, i, j);
			}
		} cout << ans - 1 << '\n';
	} return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值