P5684 [CSP-J2019 江西] 非回文串 题解

news2025/6/5 12:43:22

https://www.luogu.com.cn/problem/P5684

/*
比较简单的组合计数
题目没有以文字去描述,而是用下标来形式化题意,给我们一个关键信息:判定两个串是否相同不是看字符是否相同,而是看下标
换言之就是相同的字符,如果下标不同就算不同。这实际上更好算了

进入正题:直接算非回文串很难,考虑正难则反,用总数n!减去回文串个数,就是非回文串个数
首先桶排,如果有>1种字符的数量为奇数,显然永远不可能排列成回文串(答案n!)
然后想想回文串个数怎么算:由于回文串的对称性考虑把回文串劈成两半,先确定一半里的字符,然后另一半的自然就对称过去了

分情况讨论:(设t为桶数组)
1.所有字符个数都为偶数。直接按照上面的说法对称:(n/2)! * (t[1]!×t[2]!×...×t[26]!) / [(t[1]/2)!×(t[2]/2)!×...×(t[26]/2)!] = $\frac{\left(\frac{n}{2}\right)! \cdot \prod_{i = 1}^{26} t[i]!}{\prod_{i = 1}^{26} \left(\frac{t[i]}{2}\right)!}$
 组合意义:先确定左半边的排列(n/2)!,然后乘上变换下标顺序的方案数(为阶乘级别),但这样会多算因为(n/2)!已经考虑过左半边的顺序了,所以把这部分除掉,仅保留右边不同下标顺序的排列数
还有一种算法,先一个一个选左边哪些位置排什么字符(组合数),再乘上全排列的下标顺序方案数:
 =C(n/2,t[1]/2) * C(n/2-t[1]/2,t[2]/2) * C(n/2-t[1]/2-t[2]/2,t[3]/2) *...* (t[1]!×t[2]!×...×t[26]!)
 化简后是一样的

2.只有一个字符个数为奇数,就把是奇数的那个排在最中间,然后两边对称排即可(就是在上面的情况下多乘一个选中间位置下标的方案数):
坑点:如果有出现奇数个的,在最中间的那个已经固定,所以要少算一次!!!
设字符p出现奇数次,=(n/2)! * (t[1]!×t[2]!×...×(t[p]-1)!×...×t[26]!) / [(t[1]/2)!×(t[2]/2)!×...×((t[p]-1)/2)!×...×(t[26]/2)!] * t[p] = $(\frac{n}{2})! \times \frac{(t[1]! \times t[2]! \times \cdots \times (t[p]-1)! \times \cdots \times t[26]!)}{(\frac{t[1]}{2}!) \times (\frac{t[2]}{2}!) \times \cdots (\frac{t[p]-1}{2}!) \times \cdots \times (\frac{t[26]}{2}!)} \cdot t[p]$

考虑预处理一个阶乘和阶乘逆元即可
*/

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2005, mod = 1e9 + 7;

ll Pow(ll x, ll y){
    ll ans = 1;
    while(y){
        if(y & 1) ans=ans*x%mod;
        x=x*x%mod, y>>=1;
    }
    return ans;
}

int n, t[26];
string s;
ll fac[maxn], ifac[maxn];

void solve()
{
    cin >> n >> s;

    // 预处理
    fac[0] = 1;
    for(int i = 1; i <= n; i ++){
        fac[i] = fac[i - 1] * i % mod;
    }
    ifac[n] = Pow(fac[n], mod - 2);
    for(int i = n - 1; i >= 0; i --){
        ifac[i] = ifac[i + 1] * (i + 1) % mod;
    }

    // 桶排 + 特判
    for(char c : s) t[c-'a'] ++;
    bool flag = false; int p = -1; // 是否出现个数为奇数的字符、位置
    for(int i = 0; i < 26; i ++){
        if((t[i] & 1) && flag){ // 说明不止一个字符出现奇数次,不可能出现回文串,答案即为全排列
            cout << fac[n]; return ;
        }
        else if(t[i] & 1) flag = true, p = i;
    }

    // 算答案
    ll cnt = fac[n / 2]; // 非回文串个数
    for(int i = 0; i < 26; i ++){
        if(i == p){ // 特判
            cnt = cnt * fac[t[i] - 1] % mod * ifac[(t[i] - 1) / 2] % mod;
        }else{
            cnt = cnt * fac[t[i]] % mod * ifac[t[i] / 2] % mod;
        }
    }
    if(flag) cnt = cnt * t[p] % mod;
    ll ans = (fac[n] - cnt + mod) % mod; // 别忘了加mod防止负数

    cout << ans << '\n';
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    solve();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2398053.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自适应移动平均(Adaptive Moving Average, AMA)

文章目录 1. 考夫曼自适应移动平均 (KAMA)算法推导及Python实现2. 对 (KAMA)算法参数进行优化及实现 自适应移动平均&#xff08;Adaptive Moving Average, AMA&#xff09;由Perry Kaufman在其著作《Trading Systems and Methods》中提出&#xff0c;它通过动态调整平滑系数来…

涨薪技术|0到1学会性能测试第95课-全链路脚本开发实例

至此关于系统资源监控、apache监控调优、Tomcat监控调优、JVM调优、Mysql调优、前端监控调优、接口性能监控调优的知识已分享完,今天学习全链路脚本开发知识。后续文章都会系统分享干货,带大家从0到1学会性能测试。 前面章节介绍了如何封装.h头文件,现在通过一个实例来介绍…

Spring AI Alibaba + Nacos 动态 MCP Server 代理方案

作者&#xff1a;刘宏宇&#xff0c;Spring AI Alibaba Contributor 文章概览 Spring AI Alibaba MCP 可基于 Nacos 提供的 MCP server registry 信息&#xff0c;建立一个中间代理层 Java 应用&#xff0c;将 Nacos 中注册的服务信息转换成 MCP 协议的服务器信息&#xff0c…

MCP:让AI工具协作变得像聊天一样简单 [特殊字符]

想象一下,你正在处理一个项目,需要从A平台查看团队讨论,从B平台获取客户信息,还要在GitHub上检查代码进度。传统做法是什么?打开三个不同的网页,在各个平台间来回切换,复制粘贴数据,最后还可能因为信息分散而遗漏重要细节。 听起来很熟悉?这正是当前工作流程的痛点所…

AI炼丹日志-27 - Anubis 通过 PoW工作量证明的反爬虫组件 上手指南 原理解析

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇&#xff1a; MyBatis 更新完毕目前开始更新 Spring&#xff0c;一起深入浅出&#xff01; 大数据篇 300&#xff1a; Hadoop&…

阿姆达尔定律的演进:古斯塔夫森定律

前言 在上一篇文章《使用阿姆达尔定律来提升效率》中提到的阿姆达尔定律前提是假设问题的规模保持不变&#xff0c;并且给定一台速度更快的机器&#xff0c;目标是更快地解决问题。然而&#xff0c;在大多数情况下&#xff0c;这并不完全正确。当有一台更快的机器时&#xff0…

JavaScript极致性能优化全攻略

JavaScript性能优化深度指南 1 引言 JavaScript性能优化在现代Web开发中至关重要。随着Web应用日益复杂,性能直接影响用户体验、搜索引擎排名和业务转化率。研究表明,页面加载时间每增加1秒,转化率下降7%,跳出率增加32%。通过优化JavaScript性能,开发者可以: 提升用户满…

Transformer核心原理

简介 在人工智能技术飞速发展的今天&#xff0c;Transformer模型凭借其强大的序列处理能力和自注意力机制&#xff0c;成为自然语言处理、计算机视觉、语音识别等领域的核心技术。本文将从基础理论出发&#xff0c;结合企业级开发实践&#xff0c;深入解析Transformer模型的原…

Grafana-State timeline状态时间线

显示随时间推移的状态变化 状态区域&#xff1a;即状态时间线上的状态显示的条或带&#xff0c;区域长度表示状态持续时间或频率 数据格式要求&#xff08;可视化效果最佳&#xff09;&#xff1a; 时间戳实体名称&#xff08;即&#xff1a;正在监控的目标对应名称&#xf…

解决CSDN等网站访问不了的问题

原文网址&#xff1a;解决CSDN等网站访问不了的问题-CSDN博客 简介 本文介绍解决CSDN等网站访问不了的方法。 问题描述 CSDN访问不了了&#xff0c;页面是空的。 问题解决 方案1&#xff1a;修改DNS 可能是dns的问题&#xff0c;需要重新配置。 国内常用的dns是&#x…

C++ Vector算法精讲与底层探秘:从经典例题到性能优化全解析

前引&#xff1a;在C标准模板库&#xff08;STL&#xff09;中&#xff0c;vector作为动态数组的实现&#xff0c;既是算法题解的基石&#xff0c;也是性能优化的关键战场。其连续内存布局、动态扩容机制和丰富的成员函数&#xff0c;使其在面试高频题&#xff08;如LeetCode、…

Flowith,有一种Agent叫无限

大家好&#xff0c;我是羊仔&#xff0c;专注AI工具、智能体、编程。 今天羊仔要和大家聊聊一个最近发现的超级实用的Agent平台&#xff0c;名字叫Flowith。 这篇文章会带你从零了解到实战体验&#xff0c;搞清楚Flowith是如何让工作效率飙升好几倍&#xff0c;甚至重新定义未…

系统思考:短期利益与长期系统影响

一个决策难题&#xff1a;一家公司接到了一个大订单&#xff0c;客户提出了10%的降价要求&#xff0c;而企业的产能还无法满足客户的需求。你会选择增加产能&#xff0c;接受这个订单&#xff0c;还是拒绝&#xff1f;从系统思考的角度来看&#xff0c;这个决策不仅仅是一个简单…

HTTP连接管理——短连接,长连接,HTTP 流水线

连接管理是一个 HTTP 的关键话题&#xff1a;打开和保持连接在很大程度上影响着网站和 Web 应用程序的性能。在 HTTP/1.x 里有多种模型&#xff1a;短连接、_长连接_和 HTTP 流水线。 下面分别来详细解释 短连接 HTTP 协议最初&#xff08;0.9/1.0&#xff09;是个非常简单的…

【免费】2004-2020年各省电力消费量数据

2004-2020年各省电力消费量数据 1、时间&#xff1a;2004-2020年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;行政区划代码、地区、年份、电力消费量(亿千瓦小时) 4、范围&#xff1a;31省 5、指标说明&#xff1a;电力消费量是指在一定时期内&#xff…

登录的写法,routerHook具体配置,流程

routerHook挂在在index.js/main.js下的&#xff0c;找不到可以去那边看一下 vuex需要做的&#xff1a; //创建token的sate&#xff0c;从本地取 let token window.localStorage.getItem(token) // 存储用户登录信息let currentUserInfo reactive({userinfo: {}}) //存根据不…

工作服/反光衣检测算法AI智能分析网关V4安全作业风险预警方案:筑牢矿山/工地/工厂等多场景安全防线

一、方案背景​ 在工地、矿山、工厂等高危作业场景&#xff0c;反光衣是保障人员安全的必备装备。但传统人工巡查存在效率低、易疏漏等问题&#xff0c;难以实现实时监管。AI智能分析网关V4基于人工智能技术&#xff0c;可自动识别人员着装状态&#xff0c;精准定位未穿反光衣…

设计模式——中介者设计模式(行为型)

摘要 文章详细介绍了中介者设计模式&#xff0c;这是一种行为型设计模式&#xff0c;通过中介者对象封装多个对象间的交互&#xff0c;降低系统耦合度。文中阐述了其核心角色、优缺点、适用场景&#xff0c;并通过类图、时序图、实现方式、实战示例等多方面进行讲解&#xff0…

MinGW-w64的安装详细步骤(c_c++的编译器gcc、g++的windows版,win10、win11真实可用)

文章目录 1、MinGW的定义2、MinGW的主要组件3、MinGW-w64下载与安装 3.1、下载解压安装地址3.2、MinGW-w64环境变量的设置 4、验证MinGW是否安装成功5、编写一段简单的代码验证下6、总结 1、MinGW的定义 MinGW&#xff08;Minimalist GNU for Windows&#xff09; 是一个用…

LabVIEW磁悬浮轴承传感器故障识别

针对工业高端装备中主动磁悬浮轴承&#xff08;AMB&#xff09;的位移传感器故障检测需求&#xff0c;基于 LabVIEW 平台构建了一套高精度故障识别系统。通过集成品牌硬件与 LabVIEW 的信号处理能力&#xff0c;实现了传感器探头故障的实时监测与精准定位&#xff0c;解决了传统…