题目链接
F.组合数问题
题目描述
小 M M 很喜欢组合数。
小 Z Z 给了她一个数 n n ( n n 为偶数) ,让她计算 ( n 0 ) + ( n 2 ) + ( n 4 ) . . + ( n n ) ( n 0 ) + ( n 2 ) + ( n 4 ) . . + ( n n ) ,小 M M 一下就秒掉了,觉得题好简单。
因此,小Z Z 给了她一个难题: 给定一个数 n n ( n n 是4 4 的倍数),计算 ( n 0 ) + ( n 4 ) + ( n 8 ) + … + ( n n ) ( n 0 ) + ( n 4 ) + ( n 8 ) + … + ( n n ) ,答案对 998244353 998244353 取模。
小 M M 不会做,请你来帮帮她吧!
输入描述:
输入一个数 n n 。
输出描述:
输出答案对 998244353 998244353 取模的值。
解题思路
数论,复数快速幂
S 1 = ( 1 + 1 ) n + ( 1 − 1 ) n = 2 ( ( n 0 ) + ( n 2 ) + … + ( n n ) ) S 2 = ( 1 + i ) n + ( 1 − i ) n = 2 ( ( n 0 ) − ( n 2 ) + … + ( n n ) ) S 1 + S 2 = 4 ( ( n 0 ) + ( n 4 ) + … + ( n n ) ) 所 以 原 式 = 2 n + ( 1 + i ) n + ( 1 − i ) n 4 , 用 复 数 快 速 幂 即 可 S 1 = ( 1 + 1 ) n + ( 1 − 1 ) n = 2 ( ( n 0 ) + ( n 2 ) + … + ( n n ) ) S 2 = ( 1 + i ) n + ( 1 − i ) n = 2 ( ( n 0 ) − ( n 2 ) + … + ( n n ) ) S 1 + S 2 = 4 ( ( n 0 ) + ( n 4 ) + … + ( n n ) ) 所以原式 = 2 n + ( 1 + i ) n + ( 1 − i ) n 4 ,用复数快速幂即可
代码
#include <bits/stdc++.h>
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair<int , int > PII;
typedef pair<LL, LL> PLL;
template <typename T> bool chkMax (T &x, T y) { return (y > x) ? x = y, 1 : 0 ; }
template <typename T> bool chkMin (T &x, T y) { return (y < x) ? x = y, 1 : 0 ; }
template <typename T> void inline read (T &x) {
int f = 1 ; x = 0 ; char s = getchar ();
while (s < '0' || s > '9' ) { if (s == '-' ) f = -1 ; s = getchar (); }
while (s <= '9' && s >= '0' ) x = x * 10 + (s ^ 48 ), s = getchar ();
x *= f;
}
const int mod=998244353 ;
LL n;
struct Complex
{
LL x,y;
Complex (LL _x,LL _y)
{
x=_x,y=_y;
}
};
void mul (Complex &a,Complex b,int p)
{
LL x=((a.x*b.x-a.y*b.y)%p+p)%p;
LL y=((a.x*b.y+a.y*b.x)%p+p)%p;
a={x,y};
}
void add (Complex &a,Complex b,int p)
{
a.x=(a.x+b.x)%p;
a.y=(a.y+b.y)%p;
}
Complex ksm (Complex a,LL b,int p)
{
Complex res (1 ,0 ) ;
while (b)
{
if (b&1 )mul (res,a,p);
mul (a,a,p);
b>>=1 ;
}
return res;
}
int ksm (int a,int b,int p)
{
int res=1 ;
while (b)
{
if (b&1 )
res=1ll *res*a%p;
a=1ll *a*a%p;
b>>=1 ;
}
return res;
}
int main ()
{
cin>>n;
auto res=ksm ({2 ,0 },n,mod);
add (res,ksm ({1 ,1 },n,mod),mod),add (res,ksm ({1 ,-1 },n,mod),mod);
mul (res,ksm ({4 ,0 },mod-2 ,mod),mod);
cout<<res.x;
return 0 ;
}
G.机器人
题目描述
题目描述
有 n n 个机器人,每个机器人会读入一个 x x ,并返回 a x + b a x + b 。
现在银临姐姐手里有一个数 x x ,她想将机器人按某种顺序排列,使得最终返回得到的 x x 尽可能大。
但是计算量太大啦,请你编个程序帮帮她吧。
输入描述:
第一行读入 n , x n , x ,接下来 n n 行依次输入 a i , b i a i , b i 。
输出描述:
输出最大值。
示例1
输入
输出
备注:
对于所有的数据,1 ≤ n , x , a i , b i ≤ 20 1 ≤ n , x , a i , b i ≤ 20 。
解题思路
贪心
只考虑两个机器人的话,有这样的顺序:( a i , b i ) , ( a j , b j ) ( a i , b i ) , ( a j , b j ) ,则有:a j × ( a i x + b i ) + b j ≥ a i × ( a j x + b j ) + b i a j × ( a i x + b i ) + b j ≥ a i × ( a j x + b j ) + b i ,即 a i b j + b i ≤ a j b i + b j a i b j + b i ≤ a j b i + b j ,对于多个机器人,如果存在相邻两项不满足这样的关系,则交换后会更优,另外注意会爆long long
状压dp
状态表示:f [ i ] f [ i ] 表示选择状态为 i i 时的最大值
状态计算:f [ j ] = m a x ( f [ j ] , f [ i ] ∗ a [ t ] . f i + a [ t ] . s e ) f [ j ] = m a x ( f [ j ] , f [ i ] ∗ a [ t ] . f i + a [ t ] . s e ) ,可以转移当且仅当 j j 比 i i 在某位 t t 上多一
时间复杂度:O ( n × 2 n ) O ( n × 2 n )
代码
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!