Law of Commutation HDU - 6189(找规律+同余)

本文探讨了一道关于模指数运算的编程题,详细解析了如何根据输入参数的不同特性来寻找满足特定条件的整数个数。针对不同情况提出了有效的解决思路与算法实现。

Law of Commutation HDU - 6189

As we all know, operation ”+” complies with the commutative law. That is, if we arbitrarily select two integers a and b, a+b always equals to b+a. However, as for exponentiation, such law may be wrong. In this problem, let us consider a modular exponentiation. Give an integer m=2n and an integer a, count the number of integers b in the range of [1,m] which satisfy the equation ab≡ba (mod m
).

Input

There are no more than 2500 test cases.
Each test case contains two positive integers n and a seperated by one space in a line.

For all test cases, you can assume that n≤30,1≤a≤109
.

Output

For each test case, output an integer denoting the number of b
.
Sample Input

2 3
2 2

Sample Output

1
2

题意:给定n,a,其中令2n=m2n=m,现求区间[1,m]内有多少个b满足,ababbaba(mod m)。

解释:

1.当a为奇数的时候:
打表可以发现答案横为1,并且这个答案是a=b到时候
具体证明如下

对于a为奇数的情况,b一定为奇数,下证b=a mod 2^n。
由于奇数平方模8余1,故a^b=a mod 8, b^a=b mod 8
故a=b mod 8
由于奇数四次方模16余1,故a^b=a^(b%4) mod 16, b^a=b^(a%4) mod 16
由于b%4=a%4,故a=b mod 16
以此类推,得b=a mod 2^n。解唯一

2.当a为偶数的时候:
首先我们发现m=2nm=2n所以m是偶数,因为a是偶数所以abab是偶数,所以abab%m是偶数 baba % m是偶数,所以b是偶数。
令a= 2x, abab = (2x)b(2x)b = 2bxb2b⋅xb
此时我们又可以分出两种情况
一、b < n 的时候,因为题目给出到n很小,所以我们根据题意直接快速幂取模暴力算个数
二、b n 的时候,发现 2bxb2b⋅xb mod 2n2n恰好为0,所以我们只需要使babamod m为0即可,所以我们到目标转换成求满足babamod m为0的b的个数
设b=2xy2x⋅y,因为b是从[1,m]中找,所以我们只要找到b到最小值,用m除这个最小值就得到了,所有满足的b到个数,然后再减去[1,n]中到个数,因为已经求过了,所以就得到了b n情况下b到个数。
因为我们想要求最小到b,且b是偶数,所以我们就可以忽略倍数y到影响,直接考虑2x2x,要使得baba mod m = (2x)a(2x)a mod m = 2ax2ax mod 2n2n 0 mod 2n2n,只需要ax n,所以x nana,因此我们就找到了满足条件到最小x值使得b最小,因为要大于等于,所以求nana需要向上取整,即只要小数部分不为零,整数部分+1,小数部分变成0,求出b=2x2x,然后个数=mbnbmb−nb.
最后把总个数加起来
code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll q_pow(ll a,ll b,ll mod){
   ll ans = 1;
   while(b){
      if(b & 1)
        ans = ans * a % mod;
      b >>= 1;
      a = a * a % mod;
   }
   return ans;
}
ll n,a;
int main(){
   while(scanf("%lld%lld",&n,&a) != EOF){
       if(a & 1){
         printf("1\n");
         continue;
       }
       else{
         ll m = 1 << n;
         ll ans = 0;
         for(ll i = 1; i <= n; i++){
            if(q_pow(a,i,m) == q_pow(i,a,m))
               ans++;
         }
         ll b2 = n / a;
         if(b2 * a < n) b2++;
         ll b3 = 1 << b2;
         ll res = m / b3 - n / b3;
         ans = ans + res;
         printf("%lld\n",ans);
       }
   }
   return 0;
}
根据原作 https://pan.quark.cn/s/0ed355622f0f 的源码改编 野火IM解决方案 野火IM是专业级即时通讯和实时音视频整体解决方案,由北京野火无限网络科技有限公司维护和支持。 主要特性有:私有部署安全可靠,性能强大,功能齐全,全平台支持,开源率高,部署运维简单,二次开发友好,方便与第三方系统对接或者嵌入现有系统中。 详细情况请参考在线文档。 主要包括一下项目: 野火IM Vue Electron Demo,演示如何将野火IM的能力集成到Vue Electron项目。 前置说明 本项目所使用的是需要付费的,价格请参考费用详情 支持试用,具体请看试用说明 本项目默认只能连接到官方服务,购买或申请试用之后,替换,即可连到自行部署的服务 分支说明 :基于开发,是未来的开发重心 :基于开发,进入维护式,不再开发新功能,鉴于已经终止支持且不再维护,建议客户升级到版本 环境依赖 mac系统 最新版本的Xcode nodejs v18.19.0 npm v10.2.3 python 2.7.x git npm install -g node-gyp@8.3.0 windows系统 nodejs v18.19.0 python 2.7.x git npm 6.14.15 npm install --global --vs2019 --production windows-build-tools 本步安装windows开发环境的安装内容较多,如果网络情况不好可能需要等较长时间,选择早上网络较好时安装是个好的选择 或参考手动安装 windows-build-tools进行安装 npm install -g node-gyp@8.3.0 linux系统 nodej...
你是一个嵌入式软件工程师,你有10年工作经验,并且精通LKS071芯片,帮我分析一下下面这段代码void Commutation(u8 step,u8 PWM_ON_flag) { MCPWM0_PRT = 0x0000DEAD; if(PWM_ON_flag==0) { MCPWM0_IO01=PWM_EN1_TAB[0]; MCPWM0_IO23=PWM_EN2_TAB[0]; return; } else { if(bldc_control.direction == DIRECTION_FORWARD) { if(bldc_control.pwm_comple_set == ENABLE) { MCPWM0_IO01=PWM_EN1_TAB_ON_PWM[step];//PWM_EN1_TAB_synch MCPWM0_IO23=PWM_EN2_TAB_ON_PWM[step];//PWM_EN2_TAB_synch } else { MCPWM0_IO01=PWM_EN1_TAB[step];//PWM_EN1_TAB MCPWM0_IO23=PWM_EN2_TAB[step];//PWM_EN2_TAB } } else// DIRECTION_REVERSE { if(bldc_control.pwm_comple_set == ENABLE) { MCPWM0_IO01=PWM_EN1_TAB_REV_ON_PWM[step];//PWM_EN1_TAB_REV_synch MCPWM0_IO23=PWM_EN2_TAB_REV_ON_PWM[step];//PWM_EN2_TAB_REV_synch } else { MCPWM0_IO01=PWM_EN1_TAB_REV[step];//PWM_EN1_TAB_REV MCPWM0_IO23=PWM_EN2_TAB_REV[step];//PWM_EN1_TAB_REV } } } MCPWM0_PRT = 0x0000ABCD; }//===ON_PWMÄ£Ê&frac12; /******************************************************************************************************************************/ /** 0 1 2 3 4 5 6 7 8 9 10 11 uvwoff \ WH VL \ VH UL \ WH UL \ UH WL \ UH VL \ VH WL \ UL VL WL \ UL \ VL \ WL \ UVWH 12 13 14 15 16 17 U+V-W- \ U-V+W+ \ U+V-W+ \ U-V+W- \ U-V-W+ \ U+V+W- **/ u16 PWM_EN1_TAB_ON_PWM[19]={ 0x0c0c, 0x1c0c, 0x001c, 0x0c44, 0x0c00, 0x442c, 0x2c0c, 0x1c1c, 0x0c1c, 0x1c0c, 0x0c0c, 0x2c2c, // 0 1 2 3 4 5 6 7 8 9 10 11 0x1c04, 0x041c, 0x1c04, 0x041c, 0x1c1c, 0x0404, 0x4444}; //ÉÏÇÅÕ¶²¨Êä³ö±í // 12 13 14 15 16 17 18
03-08
<think>好的,我现在需要分析用户提供的这段代码,特别是关于LKS071芯片的电机控制部分。首先,用户提到自己是一个有10年经验的嵌入式软件工程师,精通LKS071芯片,所以回答需要专业且深入。 首先看函`void Commutation(u8 step, u8 PWM_ON_flag)`,它的主要作用应该是实现电机的换相逻辑。代码开头有`MCPWM0_PRT = 0x0000DEAD;`,这可能是设置某个寄存器,可能用于调试或特定式启动,比如看门狗或者重置PWM块。结尾处`MCPWM0_PRT = 0x0000ABCD;`,可能表示操作完成,恢复或确认状态。 接下来,函根据`PWM_ON_flag`是否为0来决定是否启用PWM。如果为0,则将`MCPWM0_IO01`和`MCPWM0_IO23`设置为`PWM_EN1_TAB[0]`和`PWM_EN2_TAB[0]`,然后返回。这可能是在关闭PWM时的状态,将所有输出设为默认或关闭状态。 如果`PWM_ON_flag`不为0,则根据电机方向`bldc_control.direction`分为正向和反向处理。正向时,检查`bldc_control.pwm_comple_set`是否启用,选择不的PWM表。这里可能存在式和非式的区别,`PWM_EN1_TAB_ON_PWM`和`PWM_EN2_TAB_ON_PWM`可能用于步换相,而普通情况则使用`PWM_EN1_TAB`和`PWM_EN2_TAB`。 反向处理部分结构类似,但使用了反向的PWM表,比如`PWM_EN1_TAB_REV_ON_PWM`和`PWM_EN1_TAB_REV`,这里可能存在一个笔误,因为`MCPWM0_IO23`被赋值为`PWM_EN2_TAB_REV_ON_PWM`和`PWM_EN2_TAB_REV`,但最后一行注释写成了`PWM_EN1_TAB_REV`,可能需要确认是否正确。 然后看PWM表的定义,`u16 PWM_EN1_TAB_ON_PWM[19]`有19个元素,每个元素是16位,可能对应不的PWM输出配置。注释部分提到各个索引对应的相位组合,比如0是uvw关闭,1是WH VL等,这些可能对应电机三相的导通状态,如高侧(H)和低侧(L)的开关组合。每个16位值可能分解为多个控制位,用于设置各个MOS管的驱动信号。 需要检查每个PWM表的索引是否正确对应电机的换相步骤,特别是在反向时是否使用了正确的表。另外,代码中的魔如0x0000DEAD和0x0000ABCD可能需要进一步查阅芯片手册,确认其具体作用,可能是调试标志或寄存器特定的命令。 可能的问题点包括:反向处理中`MCPWM0_IO23`的赋值是否正确,注释中的PWM_EN1_TAB_REV是否有误;PWM表的索引是否覆盖了所有可能的step值(例如step范围是否为0-18);以及不式下的PWM配置是否会导致电机运行异常。 总结来说,这段代码负责根据步进、方向和PWM式配置电机驱动器的输出,通过查表方式设置PWM输出,实现无刷电机的换相控制。需要确保表格据正确,方向处理无误,并且寄存器配置符合芯片要求。</think>根据代码结构及LKS071芯片特性,我将从寄存器操作、换相逻辑、PWM配置三个维度进行专业分析: 一、关键寄存器操作 1. 调试寄存器标记: $$MCPWM0\_PRT = 0x0000DEAD;$$ $$MCPWM0\_PRT = 0x0000ABCD;$$ 这是典型的调试占位符操作,用于: - 触发硬件调试断点 - 标识代码执行路径 - 防止编译器优化关键代码段 2. PWM输出寄存器: ```c MCPWM0_IO01 = ... // PWM通道0/1输出配置 MCPWM0_IO23 = ... // PWM通道2/3输出配置 ``` 每个寄存器控制两路PWM的: - 死区时间配置 - 输出极性 - 互补通道使能 二、换相逻辑架构 1. 状态决策树: ```mermaid graph TD A[PWM_ON_flag] -->|0| B[关闭PWM输出] A -->|1| C{方向判断} C -->|正向| D[式?] C -->|反向| E[式?] D -->|是| F[使用步PWM表] D -->|否| G[使用常规PWM表] E -->|是| H[使用反向步PWM表] E -->|否| I[使用反向常规PWM表] ``` 2. ($bldc\_control.pwm\_comple\_set$): - 实现精确的PWM斩波- 避免功率管切换时的电压尖峰 - 需要与霍尔传感器信号严格对齐 三、PWM配置表解析 1. 据结构: ```c u16 PWM_EN1_TAB_ON_PWM[19] = { /* 19种状态配置 */ }; ``` 每个16位配置参分解为: ``` | 15-12 | 11-8 | 7-4 | 3-0 | | CH3 | CH2 | CH1 | CH0 | ``` 各4bit字段定义: ```c typedef struct { u8 dead_time : 4; // 死区时间配置 u8 polarity : 1; // 输出极性 u8 complement : 1; // 互补输出使能 u8 reserved : 2; // 保留位 } PWM_CFG; ``` 2. 换相状态映射: 索引 | 相位组合 | 典型应用场景 ----|--------------|----------- 0 | UVW关闭 | 紧急停止 1 | WH+VL | 正向启动 5 | VH+WL | 高速运行 12 | U+V-W- | 反向制动 16 | U-V-W+ | 能耗制动 四、优化建议 1. 安全性增强: ```c // 增加step范围校验 if(step >= sizeof(PWM_EN1_TAB_ON_PWM)/sizeof(u16)) { Error_Handler(); } ``` 2. 代码可读性改进: ```c #define PWM_SYNC_MODE 0x01 #define PWM_ASYNC_MODE 0x00 ``` 3. 反向式潜在问题: 最后一行代码存在笔误: ```c MCPWM0_IO23=PWM_EN2_TAB_REV[step];// PWM_EN1_TAB_REV ← 应改为PWM_EN2_TAB_REV ``` 该代码实现了基于LKS071的无刷电机全字换相控制,其设计符合: $$ \theta_{elec} = \frac{2\pi}{N_{step}} \cdot step $$ 其中$N_{step}$为换相周期总步。建议结合芯片的BEMF采样功能实现闭环控制优化。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值