ICPC-day1(NTT)

news2024/11/28 11:31:28

NTT经典例题

CCPC-Winter-Camp-day6-A——NTT经典例题

对于上面格式,如果想求出每个i的值可以使用卷积求出,因为阶乘j和阶乘i-j相乘的值为(i+(i-j))=i

补充一个二次剩余定理

P5491 【模板】二次剩余 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<numeric>
#include<cstring>//rfind("string"),s.find(string,begin)!=s.npos,find_first _of(),find_last_of()
#include<string>//to_string(value),s.substr(int begin, int length);
#include<cstdio>
#include<cmath>
#include<vector>//res.erase(unique(res.begin(), res.end()), res.end()),resize(n)//size of vector,vector<int>().swap(at[mx])
#include<queue>//priority_queue(big)  /priority_queue<int, vector<int>, greater<int>> q(small)
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
#include<random>
#include<chrono>
//#include<ext/pb_ds/assoc_container.hpp>//gp_hash_table
//#include<ext/pb_ds/hash_policy.hpp>
//using namespace __gnu_pbds;
std::mt19937_64 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
using namespace std;
#define int long long//__int128 2^127-1(GCC)
#define PII pair<int,int>
struct num {
	int x;// 实部
	int y;// 虚部(即虚数单位√w的系数)
};

int t, w, n, p;

num mul(num a, num b, int p) {// 复数乘法 
	num res;
	res.x = ((a.x * b.x % p + a.y * b.y % p * w % p) % p + p) % p;// x = a.x*b.x + a.y*b.y*w
	res.y = ((a.x * b.y % p + a.y * b.x % p) % p + p) % p;// y = a.x*b.y + a.y*b.x
	return res;
}
int qpow_r(int a, int b, int p) {// 实数快速幂 
	int res = 1;
	while (b) {
		if (b & 1) res = res * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return res;
}
int qpow_i(num a, int b, int p) {// 复数快速幂  
	num res = { 1,0 };
	while (b) {
		if (b & 1) res = mul(res, a, p);
		a = mul(a, a, p);
		b >>= 1;
	}
	return res.x % p;// 只用返回实数部分,因为虚数部分没了 
}
int cipolla(int n, int p) {
	n %= p;
	if (qpow_r(n, (p - 1) / 2, p) == -1 + p) return -1;// 据欧拉准则判定是否有解 

	int a;
	while (1) {// 找出一个符合条件的a
		a = rand() % p;
		w = (((a * a) % p - n) % p + p) % p;// w = a^2 - n,虚数单位的平方
		if (qpow_r(w, (p - 1) / 2, p) == -1 + p) break;
	}

	num x = { a,1 };
	return qpow_i(x, (p + 1) / 2, p);
}
signed main() {
	srand(time(0));
	cin >> t;
	while (t--) {
		cin >> n >> p;
		if (!n) {
			printf("0\n");
			continue;
		}

		int ans1 = cipolla(n, p), ans2 = -ans1 + p;// 另一个解就是其相反数,ans1正数解 
		if (ans1 == -1) printf("Hola!\n");//无解
		else {
			if (ans1 > ans2) swap(ans1, ans2);
			if (ans1 == ans2) printf("%lld\n", ans1);
			else printf("%lld %lld\n", ans1, ans2);
		}
	}

	return 0;
}

NTT背包合并

NN​​​​​​​Fly (nowcoder.com)

PowerPoint 演示文稿 (nowcoder.com)

有点像数位dp,其中用到背包合并可以使用多项式解决,如果n个背包合并可以使用线段树和启发式合并类似的思想

//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<numeric>
#include<cstring>//rfind("string"),s.find(string,begin)!=s.npos,find_first _of(),find_last_of()
#include<string>//to_string(value),s.substr(int begin, int length);
#include<cstdio>
#include<cmath>
#include<vector>//res.erase(unique(res.begin(), res.end()), res.end()),resize(n)//size of vector,vector<int>().swap(at[mx])
#include<queue>//priority_queue(big)  /priority_queue<int, vector<int>, greater<int>> q(small)
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
#include<random>
#include<chrono>
//#include<ext/pb_ds/assoc_container.hpp>//gp_hash_table
//#include<ext/pb_ds/hash_policy.hpp>
//using namespace __gnu_pbds;
std::mt19937_64 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
using namespace std;
#define int long long//__int128 2^127-1(GCC)
#define PII pair<int,int>
const int N = 3e6 + 5, mod = 998244353;
namespace ntt {
    const int g = 3;
    int a[N], b[N];
    int r[N], tot, bit;
    int invg;
    int qpow(int a, int b) {
        int res = 1;
        while (b) {
            if (b & 1) res = 1ll * res * a % mod;
            a = 1ll * a * a % mod;
            b >>= 1;
        }
        return res;
    }
    void add(int& a, int b) {
        a += b;
        if (a >= mod) a -= mod;
    }
    void NTT(int a[], int inv) {
        for (int i = 0; i < tot; i++)
            if (i < r[i])
                swap(a[i], a[r[i]]);
        for (int mid = 1; mid < tot; mid <<= 1) {
            int g1 = qpow(inv == 1 ? g : invg, (mod - 1) / (mid << 1));
            for (int i = 0; i < tot; i += mid << 1) {
                for (int j = 0, gk = 1; j < mid; j++, gk = 1ll * gk * g1 % mod) {
                    int x = a[i + j], y = 1ll * gk * a[i + j + mid] % mod;
                    a[i + j] = (x + y) % mod, a[i + j + mid] = (x - y + mod) % mod;
                }
            }
        }
        if (inv == -1) {
            int invtot = qpow(tot, mod - 2);
            for (int i = 0; i < tot; i++) {
                a[i] = 1ll * a[i] * invtot % mod;
            }
        }
    }
    struct Poly {
        vector<int> coef;
        int deg;

        int& operator[](int x) {
            return coef[x];
        }

        Poly(int deg = -1) : deg(deg) {
            coef = vector<int>(deg + 1, 0);
        }

        void norm(int deg) {
            this->deg = deg;
            coef.resize(deg + 1);
        }
    };
    void init(int len) {
        bit = tot = 0;
        while ((1ll << bit) <= len) bit++;
        tot = 1ll << bit;
        for (int i = 0; i < tot; i++) a[i] = b[i] = 0;
        for (int i = 1; i < tot; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (bit - 1));
    }
    Poly operator*(const Poly& f, const Poly& g) {
        Poly res(f.deg + g.deg);
        if (f.deg <= 8 || g.deg <= 8) {
            for (int i = 0; i <= f.deg; i++)
                for (int j = 0; j <= g.deg; j++)
                    add(res[i + j], 1ll * f.coef[i] * g.coef[j] % mod);
            return res;
        }
        init(res.deg);
        copy(f.coef.begin(), f.coef.end(), a);
        copy(g.coef.begin(), g.coef.end(), b);
        NTT(a, 1), NTT(b, 1);
        for (int i = 0; i < tot; i++) a[i] = 1ll * a[i] * b[i] % mod;
        NTT(a, -1);
        copy(a, a + res.deg + 1, res.coef.begin());
        return res;
    }
    int __ = []
    {
        invg = qpow(g, mod - 2);
        return 0;
    }();
}
using namespace ntt;
signed main()
{
    ios_base::sync_with_stdio(0); cin.tie(0), cout.tie(0);
    int n, k;
    int m;
    cin >> n >> m >> k;
    vector<int>a(n + 1);
    vector<Poly>v;
    int sum = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        sum += a[i];
        Poly f(a[i]);
        f[0] = f[a[i]] = 1;
        v.emplace_back(f);
    }
    auto solve = [&](auto self, int l, int r)->Poly {
        if (l == r) return v[l];
        int mid = l + r >> 1;
        return self(self, l, mid) * self(self, mid + 1, r);
    };

    Poly f = solve(solve, 0, v.size() - 1);
    //assert(f.deg == sum);
    vector<vector<int>>ban(60, vector<int>());
    //array<vector<int>, 60>ban;
    while (k--)
    {
        int b, c;
        cin >> b >> c;
        ban[c].push_back(b);
    }
    vector<Poly>dp(2);
    dp[0].norm(0);
    dp[0][0] = 1;
    for (int i = 0; i < 60; i++) {
        Poly g = f;
        sort(ban[i].begin(), ban[i].end());
        ban[i].erase(unique(ban[i].begin(), ban[i].end()), ban[i].end());
        for (auto x : ban[i]) {
            for (int j = a[x]; j <= sum; j++) {
                g[j] -= g[j - a[x]];
                if (g[j] < 0)g[j] += mod;
            }
        }
        vector<Poly>f(2), ndp(2);
        f[0] = dp[0] * g;
        f[1] = dp[1] * g;
        for (auto t : { 0,1 }) ndp[t].norm(f[t].deg / 2);
        for (auto t : { 0,1 }) {
            for (int j = 0; j <= f[t].deg; j++) {
                if (j % 2 == (m >> i & 1)) {
                    add(ndp[t][j / 2], f[t][j]);
                }
                else if (j % 2 > (m >> i & 1)) {
                    add(ndp[1][j / 2], f[t][j]);
                }
                else {
                    add(ndp[0][j / 2], f[t][j]);
                }
            }
        }
        dp = ndp;
    }
    cout << dp[0][0] << "\n";
}

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

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

相关文章

【MySQL】DML数据操作语句和基本的DQL语句

目录 一、Mysql对数据的增删改 1. 增加数据 2. 修改数据&#xff08;UPDATE语句&#xff09; 3. 删除 3.1 delete、truncate、drop区别 二、DQL语言&#xff08;重点&#xff09; 1. 单表查询 1.1 最简单的查询 1.2 从表中获取数据 1.3 字段名起别名 1.4 添加字段 1…

[20231103消息] 大模型商业化模式详解:烧钱之后如何挣钱?

距ChatGPT3.5发布已近一年&#xff0c;大模型狂热开始逐步降温&#xff1a;GPU禁运及长期烧钱的事实&#xff0c;让国内的大模型企业&#xff0c;不得不加速商业化考量。 目前&#xff0c;大模型的B端应用已经出现各种定价方法&#xff0c;包括按照时间段收费、按调用量收费以…

class 030 异或运算的骚操作

这篇文章是看了“左程云”老师在b站上的讲解之后写的, 自己感觉已经能理解了, 所以就将整个过程写下来了。 这个是“左程云”老师个人空间的b站的链接, 数据结构与算法讲的很好很好, 希望大家可以多多支持左程云老师, 真心推荐. https://space.bilibili.com/8888480?spm_id_f…

Java中Map和Set详细介绍,哈希桶的实现

大家好呀&#xff0c;前一节我们接触了二叉搜索树&#xff0c;那么紧接着&#xff0c;我们要学习一种十分重要而且也是我们在初阶数据结构中接触的最后一种数据结构—Map和Set&#xff0c;本篇博客将会详细介绍两种数据结构&#xff0c;并且针对哈希表底层实现一个哈希桶&#…

基于元神操作系统实现NTFS文件操作(三)

1. 背景 本文主要介绍DBR的读取和解析&#xff0c;并提供了基于元神操作系统的实现代码。由于解析DBR的目的是定位到NTFS磁盘分区的元文件$Root进行文件操作&#xff0c;所以只解析了少量的部分&#xff0c;其它部分可以参考相关文档进行理解。 DBR存在于磁盘分区的第一个扇区…

《数据结构》--链表【包含跳表概念】

不知道大家对链表熟悉还是陌生&#xff0c;我们秉着基础不牢&#xff0c;地动山摇的原则&#xff0c;会一点点的介绍链表的&#xff0c;毕竟链表涉及的链式存储也很重要的。在这之前&#xff0c;我们认识过顺序存储的顺序表&#xff0c;它其实就是一个特殊的数组。那链表到底是…

树莓派 AI 摄像头(Raspberry Pi AI Camera)教程

系列文章目录 前言 人们使用 Raspberry Pi 产品构建人工智能项目的时间几乎与我们生产 Raspberry Pi 的时间一样长。随着我们发布功能越来越强大的设备&#xff0c;我们能够支持的原生应用范围也在不断扩大&#xff1b;但无论哪一代产品&#xff0c;总会有一些工作负载需要外部…

SpringBoot介绍及整合Mybatis Plus

目录 SpringBoot背景及特点 SpringBoot整合Mybatis Plus SpringBoot背景及特点 SpringBoot的设计目是抛弃之前Spring、SpringMVC繁杂的配置过程&#xff0c;简化开发过程。之前的Spring框架需要大量的手动配置&#xff0c;包括XML配置文件或Java配置类&#xff0c;配置过程繁…

深入理解 Git 一个开发者的必备工具

深入理解 Git 一个开发者的必备工具 演示地址 演示地址 获取更多 获取更多 在现代软件开发中&#xff0c;版本控制系统扮演着至关重要的角色。其中&#xff0c;Git 是最流行的选择之一。无论你是新手还是有经验的开发者&#xff0c;了解 Git 的基本概念和使用方法都能大大提…

YOLO v11实时目标检测3:训练数据集格式说明

一、Yolov11简介 YOLOv11 是 YOLO 系列的最新版本&#xff0c;它不仅在目标检测方面表现出色&#xff0c;还引入了对象分割和多目标跟踪的功能。本文将介绍如何使用 YOLOv11 进行人流统计、车流统计以及跟踪的实际应用。 二、Yolo v11训练数据集格式说明 2.1 数据组织&#…

SAT分离轴定理的c++/python实现

分离轴定理的c/python实现 现在要对BEV模型检查出来的车辆做NMS&#xff0c;把3d框的平面属性获取到后&#xff0c;配合旋转角度投影到地面就是2D图形。 开始碰撞检测&#xff0c;判断是否重叠&#xff0c;保留置信度高的框就行。 原理 分离轴定理&#xff08;Separating A…

(C语言贪吃蛇)11.贪吃蛇方向移动和刷新界面一起实现面临的问题

目录 前言 实现效果 支持方向变换 修改默认效果 如何修改 总结 前言 我们上节实现了不需要按下右键就可以是贪吃蛇自发的向右移动&#xff0c;本节我们主要来解决贪吃蛇方向移动和刷新界面所遇到的问题。 实现效果 上图是我们希望实现的效果&#xff0c;我们可以自发地控…

Go 进阶:Go + gin 极速搭建 EcommerceSys 电商系统

Go 进阶:Go + gin 极速搭建 EcommerceSys 电商系统 前言 本章节适合有一定基础的 Golang 初学者,通过简单的项目实践来加深对 Golang 的基本语法和 Web 开发的理解。 具体请联系作者 项目结构 项目流程图 技术栈 项目结构 项目路由 4. 项目模型 项目初始化 初始化项目文…

归并排序【C语言版-笔记】

目录 一、概念二、排序流程理解三、代码实现3.1主调函数3.2 merge函数 四、性能分析 一、概念 归并是一种算法思想&#xff0c;是将两个或两个一上的有序表合并成一个长度较大的有序表。若一开始无序表中有n个元素&#xff0c;可以把n个元素看作n个有序表&#xff0c;把它们两…

Java中数据转换以及字符串的“+”操作

隐式转换&#xff08;自动类型转换&#xff09; 较小范围的数据类型转成较大范围的数据类型 强制转换&#xff08;显式转换&#xff09; 将数据范围大的数据类型转换为数据范围小的数据类型 基本数据类型之间的转换 当需要将一个较大的数据类型&#xff08;如float或double…

Linux:进程控制(一)

目录 一、写时拷贝 1.创建子进程 2.写时拷贝 二、进程终止 1.函数返回值 2.错误码 3.异常退出 4.exit 5._exit 一、写时拷贝 父子进程&#xff0c;代码共享&#xff0c;不作写入操作时&#xff0c;数据也是共享的&#xff0c;当任意一方试图写入&#xff0c;便通过写时拷…

影刀RPA实战:excel相关图片操作指令解

1.实战目标 excel是工作中必不缺少的工具&#xff0c;今天我们继续使用影刀RPA来实现excel操作的便利性&#xff0c;让影刀自动化来帮我们完成工作。 2.单元格填充图片 2.1 指令说明 功能&#xff1a;向 Excel 单元格插入本地图片或网络图片&#xff0c;支持Office和WPS&…

波阻抗,是电场矢量的模值/磁场矢量的模值

波阻抗是电场复振幅除以磁场复振幅&#xff0c;最后只与介质με有关 所以磁场可用电场强度表示&#xff08;利用波阻抗&#xff09; 问题&#xff0c;复振幅是矢量&#xff0c;波阻抗的定义是复振幅的比值&#xff1f;答案&#xff1a;不是&#xff0c;很明显&#xff0c;波阻…

Web3 游戏周报(9.22 - 9.28)

回顾上周的区块链游戏概况&#xff0c;查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【9.22-9.28】Web3 游戏行业动态&#xff1a; Axie Infinity 将 Fortune Slips 的冷却时间缩短至 24 小时&#xff0c;从而提高玩家的收入。 Web3 游戏开发商 Darkbright Studios…

Pikachu-Sql Inject-搜索型注入

MySQL的搜索语句&#xff1a; select * from table where column like %text%&#xff1b; 如&#xff1a;使用引号闭合左边的引号&#xff0c; or 11 把所有数据查询出来&#xff1b; # 注释掉后面的 引号等&#xff1b; test or 11# 查询出结果&#xff1a; 注入的核心点…