UVa12298 Super Joker II

news2025/6/6 0:12:17

UVa12298 Super Joker II

  • 题目链接
  • 题意
    • 输入格式
    • 输出格式
  • 分析
  • AC 代码

题目链接

  UVa12298 Super Joker II

题意

  有一副超级扑克,包含无数张牌。对于每个正合数p,恰好有4张牌:黑桃p,红桃p,梅花p和方块p(分别用pS、pH、pC 和pD 表示)。没有其他类型的牌。
  给定一个整数n,从4种花色中各选一张牌,问有多少种组合可以使得点数之和等于n。例如,n=24的时候,有一种组合方法是4S+6H+4C+10D,下图所示。
Super Joker II
  不巧的是,有些牌已经丢失(题目会提供已经丢失的牌的列表)。并且为了让题目更有趣,我们还会提供两个正整数a和b,你的任务是按顺序输出n=a, n=a+1, n=a+2, …, n=b时的答案。

输入格式

  输入包含不超过25组数据。每组数据的第一行为3个整数a, b, c,其中c是已丢失的牌的张数。第二行包含c个不同的字符串,即已丢失的牌。这些牌形如pS, pH, pC 或者pD,其中p是一个正合数。输入结束标志为a=b=c=0。最多有一组数据满足a=1, b=50000且c≤10000,其他数据满足1≤a≤b≤100, 0≤c≤10。

输出格式

  对于每组数据,输出p 行,每行一个整数。每组数据后输出一个空行。

分析

  只需要对生成函数理解清楚了,就可以套用快速傅里叶变换(FFT)求解。初次接触FFT的话,推荐看看这篇知乎,GhostLX大佬给出了模板:

void dft(Complex a[])
{
    for (int i = 0; i < tot; i++)
    {
        if (i < rev[i])
            swap(a[i], a[rev[i]]); //只需要交换一次就行了,交换两次等于没有换
    }
    for (int mid = 1; mid < tot; mid <<= 1)
    {
        auto w1 = Complex({cos(PI / mid), sin(PI / mid)});
        for (int i = 0; i < tot; i += mid * 2)
        {
            auto wk = Complex({1, 0}); //初始为w(0,mid)
            for (int j = 0; j < mid; j++, wk = wk * w1) //单位根递推式
            {
                auto x = a[i + j], y = wk * a[i + j + mid];
                a[i + j] = x + y, a[i + j + mid] = x - y;
            }
        }
    }
}

  GhostLX大佬模板的单位根递推式像这样写wk = wk * w1,随着递推加深其实会带来精度误差的。推荐用这个模板:

namespace fft {
    #include <cmath>
    #define N 1<<21
    int res[N], tot;
    struct complex {
        double x, y;
        void operator+= (const complex &t) {
            x += t.x; y += t.y;
        }
        complex operator- (const complex &t) const {
            return {x - t.x, y - t.y};
        }
        complex operator* (const complex &t) const {
            return {x * t.x - y * t.y, x * t.y + y * t.x};
        }

    } a[N], b[N];
    
    /**
     * inv=1时求的是傅里叶变换(DFT),inv=-1时求的是傅里叶逆变换(IDFT)
     */
    void fft(complex (&a)[N], int inv) {
        for (int i=0, j=0; i<tot; ++i) { // 原地快速bit reversal
            if(j > i) {complex t = a[i]; a[i] = a[j]; a[j] = t;}
            int k = tot;
            while(j & (k >>= 1)) j &= ~k;
            j |= k;
        }
        for(int step=1; step<tot; step<<=1) {
            // 把每相邻两个“step点DFT”通过一系列蝴蝶变换合并为一个“2*step点DFT”
            double alpha = inv*M_PI / step;
            // 为求高效,我们并不是依次执行各个完整的DFT合并,而是枚举下标k
            // 对于一个下标k,执行所有DFT合并中该下标对应的蝴蝶变换,即通过E[k]和O[k]计算X[k]
            // 蝴蝶变换参考:http://en.wikipedia.org/wiki/Butterfly_diagram
            for(int k=0; k<step; k++) {
                // 计算omega^k
                complex wk = {cos(alpha*k), sin(alpha*k)};
                for(int Ek=k; Ek<tot; Ek += step<<1) { // Ek是某次DFT合并中E[k]在原始序列中的下标
                    int Ok = Ek + step; // Ok是该DFT合并中O[k]在原始序列中的下标
                    complex t = wk * a[Ok]; // 蝴蝶变换:x1 * omega^k
                    a[Ok] = a[Ek] - t;  // 蝴蝶变换:y1 = x0 - t
                    a[Ek] += t;         // 蝴蝶变换:y0 = x0 + t
                }
            }
        }
    }

    void workFFT(int n, int m) { // a[0, n], b[0, m]
        int bit = 0;
        while ((1 << bit) < n + m + 1) ++bit;
        tot = 1 << bit;
        fft(a, 1); fft(b, 1);
        for (int i=0; i<tot; ++i) a[i] = a[i] * b[i]; //点表示法直接运算
        fft(a, -1); //逆变换,点表示法转换为多项式表示法
        for (int i=0, j=m+n; i<=j; ++i) res[i]  = a[i].x / tot + 0.5; //向上取整
    }
}

AC 代码

#include <iostream>
#include <cmath>
using namespace std;

#define M 50020
#define N 1<<17
int na, nb, nc, tot; bool f[M] = {false};
struct complex {
    double x, y;
    void operator+= (const complex &t) {
        x += t.x; y += t.y;
    }
    complex operator- (const complex &t) const {
        return {x - t.x, y - t.y};
    }
    complex operator* (const complex &t) const {
        return {x * t.x - y * t.y, x * t.y + y * t.x};
    }

} a[4][N];

void fft(complex (&a)[N], int inv) {
    for (int i=0, j=0, k; i<tot; ++i) {
        if(j > i) {complex t = a[i]; a[i] = a[j]; a[j] = t;}
        for (k = tot; j & (k >>= 1); j &= ~k);
        j |= k;
    }
    for(int step=1; step<tot; step<<=1) {
        double alpha = inv*M_PI / step;
        for(int k=0; k<step; k++) {
            complex wk = {cos(alpha*k), sin(alpha*k)};
            for(int Ek=k; Ek<tot; Ek += step<<1) {
                int Ok = Ek + step; complex t = wk * a[Ok];
                a[Ok] = a[Ek] - t; a[Ek] += t;
            }
        }
    }
}

void solve() {
    int bit = 0; tot = (nb<<1) | 1;
    while ((1 << bit) < tot) ++bit;
    tot = 1 << bit;
    for (int i=0; i<tot; ++i) a[0][i] = a[1][i] = a[2][i] = a[3][i] = {i<nb && f[i] ? 1. : 0., 0.};
    while (nc--) {
        int v; char h; cin >> v >> h;
        a[h == 'S' ? 0 : (h == 'H' ? 1 : (h == 'C' ? 2 : 3))][v].x = 0.;
    }
    for (int i=0; i<4; ++i) fft(a[i], 1);
    for (int i=0; i<tot; ++i) a[0][i] = a[0][i] * a[1][i], a[2][i] = a[2][i] * a[3][i];
    fft(a[0], -1); fft(a[2], -1);
    for (int i=0; i<tot; ++i) a[0][i] = {i<nb ? a[0][i].x / tot : 0., 0.}, a[2][i] = {i<nb ? a[2][i].x / tot : 0., 0.};
    fft(a[0], 1); fft(a[2], 1);
    for (int i=0; i<tot; ++i) a[0][i] = a[0][i] * a[2][i];
    fft(a[0], -1);
    for (int i=na; i<=nb; ++i) cout << (long long)(a[0][i].x / tot + .5) << endl;
    cout << endl;
}

int main() {
    for (int i=2; i*i<M; ++i) if (!f[i]) for (int j=i*i; j<M; j+=i) f[j] = true;
    while (cin >> na >> nb >> nc && (na || nb || nc)) solve();
    return 0;
}

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

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

相关文章

【网络安全】SRC漏洞挖掘思路/手法分享

文章目录 Tip1Tip2Tip3Tip4Tip5Tip6Tip7Tip8Tip9Tip10Tip11Tip12Tip13Tip14Tip15Tip16Tip17Tip18Tip19Tip20Tip21Tip22Tip23Tip24Tip25Tip26Tip27Tip28Tip29Tip30Tip1 “复制该主机所有 URL”:包含该主机上的所有接口等资源。 “复制此主机里的链接”:包括该主机加载的第三…

【AFW+GRU(CNN+RNN)】Deepfakes Detection with Automatic Face Weighting

文章目录 Deepfakes Detection with Automatic Face Weighting背景pointsDeepfake检测挑战数据集方法人脸检测面部特征提取自动人脸加权门控循环单元训练流程提升网络测试时间增强实验结果Deepfakes Detection with Automatic Face Weighting 会议/期刊:CVPRW 2020 作者: …

性能优化 - 案例篇:缓冲区

文章目录 Pre1. 引言2. 缓冲概念与类比3. Java I/O 中的缓冲实现3.1 FileReader vs BufferedReader&#xff1a;装饰者模式设计3.2 BufferedInputStream 源码剖析3.2.1 缓冲区大小的权衡与默认值 4. 异步日志中的缓冲&#xff1a;Logback 异步日志原理与配置要点4.1 Logback 异…

ES101系列07 | 分布式系统和分页

本篇文章主要讲解 ElasticSearch 中分布式系统的概念&#xff0c;包括节点、分片和并发控制等&#xff0c;同时还会提到分页遍历和深度遍历问题的解决方案。 节点 节点是一个 ElasticSearch 示例 其本质就是一个 Java 进程一个机器上可以运行多个示例但生产环境推荐只运行一个…

Spring AI Advisor机制

Spring AI Advisors 是 Spring AI 框架中用于拦截和增强 AI 交互的核心组件&#xff0c;其设计灵感类似于 WebFilter&#xff0c;通过链式调用实现对请求和响应的处理5。以下是关键特性与实现细节&#xff1a; 核心功能 ‌1. 请求/响应拦截‌ 通过 AroundAdvisor 接口动态修…

Vue3 + Vite:我的 Qiankun 微前端主子应用实践指南

前言 实践文章指南 vue微前端qiankun框架学习到项目实战,基座登录动态菜单及权限控制>>>>实战指南&#xff1a;Vue 2基座 Vue 3 Vite TypeScript微前端架构实现动态菜单与登录共享>>>>构建安全的Vue前后端分离架构&#xff1a;利用长Token与短Tok…

日语输入法怎么使用罗马字布局怎么安装日语输入法

今天帮客户安装日语输入法的时候遇到了一个纠结半天的问题&#xff0c;客户一直反馈说这个输入法不对&#xff0c;并不是他要的功能。他只需要罗马字的布局&#xff0c;而不是打出来字的假名。 片假名、平假名&#xff0c;就好像英文26个字母&#xff0c;用于组成日文单词。两…

数据结构:栈(Stack)和堆(Heap)

目录 内存&#xff08;Memory&#xff09;基础 程序是如何利用主存的&#xff1f; &#x1f3af; 静态内存分配 vs 动态内存分配 栈&#xff08;stack&#xff09; 程序执行过程与栈帧变化 堆&#xff08;Heap&#xff09; 程序运行时的主存布局 内存&#xff08;Memo…

用 Vue 做一个轻量离线的“待办清单 + 情绪打卡”小工具

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

PostgreSQL数据库备份

文章目录 pg_dump 和 pg_dumpall使用 pg_dump 备份单个数据库示例 使用 pg_dumpall 备份整个数据库集群基本用法 恢复备份恢复 pg_dump 备份恢复 pg_dumpall 备份 Tips pg_dump 和 pg_dumpall 在 PostgreSQL 中&#xff0c;pg_dump 和 pg_dumpall 是两个常用的备份工具&#x…

js-day7

JS学习之旅-day7 1.事件流1.1 事件流与两个阶段说明1.2 事件捕获1.3 事件冒泡1.4 阻止1.5 解绑事件 2. 事件委托3. 其他事件3.1 页面加载事件3.2 页面滚动事件3.3 页面尺寸事件 4. 元素尺寸与位置 1.事件流 1.1 事件流与两个阶段说明 事件流指的是事件完整执行过程中的流动路…

解决Vditor加载Markdown网页很慢的问题(Vite+JS+Vditor)

1. 引言 在上一篇文章《使用Vditor将Markdown文档渲染成网页(ViteJSVditor)》中&#xff0c;详细介绍了通过Vditor将Markdown格式文档渲染成Web网页的过程&#xff0c;并且实现了图片格式居中以及图片源更换的功能。不过&#xff0c;笔者发现在加载这个渲染Markdown网页的时候…

鸿蒙5.0项目开发——横竖屏切换开发

横竖屏切换开发 【高心星出品】 文章目录 横竖屏切换开发运行效果窗口旋转配置module.json5的orientation字段调用窗口的setPreferredOrientation方法案例代码解析Index1页面代码&#xff1a;EntryAbility在module.json5的配置信息&#xff1a;Index页面的代码信息&#xff1…

Triton推理服务器部署YOLOv8(onnxruntime后端和TensorRT后端)

文章目录 一、Trition推理服务器基础知识1)推理服务器设计概述2)Trition推理服务器quickstart(1)创建模型仓库(Create a model Repository)(2)启动Triton (launching triton)并验证是否正常运行(3)发送推理请求(send a inference request)3)Trition推理服务器架…

TDengine 的 AI 应用实战——电力需求预测

作者&#xff1a; derekchen Demo数据集准备 我们使用公开的UTSD数据集里面的电力需求数据&#xff0c;作为预测算法的数据来源&#xff0c;基于历史数据预测未来若干小时的电力需求。数据集的采集频次为30分钟&#xff0c;单位与时间戳未提供。为了方便演示&#xff0c;按…

NLP学习路线图(二十一): 词向量可视化与分析

在自然语言处理&#xff08;NLP&#xff09;的世界里&#xff0c;词向量&#xff08;Word Embeddings&#xff09;犹如一场静默的革命。它将原本离散、难以捉摸的词语&#xff0c;转化为稠密、富含语义的连续向量&#xff0c;为机器理解语言铺平了道路。然而&#xff0c;这些向…

如何配置mvn镜像源为华为云

如何配置mvn镜像源为华为云 # 查找mvn 配置文件 mvn -X help:effective-settings | grep settings.xml# 配置mvn镜像源为华为云&#xff0c;/home/apache-maven-3.9.5/conf/settings.xml文件路径需要根据上一步中查询结果调整 cat > /home/apache-maven-3.9.5/conf/setting…

多模态大语言模型arxiv论文略读(105)

UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ➡️ 论文标题&#xff1a;UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ➡️ 论文作者&#xff1a;Zhaowei…

Pyhton中的命名空间包(Namespace Package)您了解吗?

在 Python 中&#xff0c;命名空间包&#xff08;Namespace Package&#xff09; 是一种特殊的包结构&#xff0c;它允许将模块分散在多个独立的目录中&#xff0c;但这些目录在逻辑上属于同一个包命名空间。命名空间包的核心特点是&#xff1a;没有 __init__.py 文件&#xff…

Azure DevOps Server 2022.2 补丁(Patch 5)

微软Azure DevOps Server的产品组在4月8日发布了2022.2 的第5个补丁。下载路径为&#xff1a;https://aka.ms/devops2022.2patch5 这个补丁的主要功能是修改了代理(Agent)二进制安装文件的下载路径&#xff1b;之前&#xff0c;微软使用这个CND(域名为vstsagentpackage.azuree…