2021icpc澳门 E-Pass the Ball!(NTT)

2023-10-31 11:59
文章标签 pass ball 澳门 ntt 2021icpc

本文主要是介绍2021icpc澳门 E-Pass the Ball!(NTT),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2021icpc澳门 E-Pass the Ball!

题意

一开始有n个小朋友1-n,手上球的编号为1-n,给一个数组a,每轮第i个小朋友会把球传给ai。有q次询问,每次询问轮数k,第k轮时每个小朋友手上的球为bi,问在这里插入图片描述是多少。(n<=1e5,q<=1e5,k<=1e9)

思路

首先很清楚的就能知道这个传球的顺序就是一个置换群,把这个置换群分解后单独去考虑每个独立的群就行,简单的说就是把这数组中环的数目分解出来。
然后在对每个环去考虑,显然一次是o(N)的,设len为当前数i所在环的长度那么(k-1+i)%len即为当前轮数该数的值在暴力for一遍求答案就行。但是题目中有q次询问,这样做就不行了,这里我们想如何能快速的处理出每个循环节内每一轮的答案,这里可以先设一个生成函数f(x)=a1 + a2x ^ 2 + a3x ^ 2 + … +akx ^ (k-1),其中k为当前环内的元素数量,这里我们发现把f(x)里面每一项的系数翻转过来与自身卷积后所得到的每一项的系数和每轮的答案有一定的关系,其中ak为第0轮的答案,而ak-1+a1为第一轮的答案后面类似这个在纸上面画画就能知道。这样我们就能 O ( n ∗ l o g n ) O(n*logn) O(nlogn)的卷出一个环内的答案了,然后合并答案的话我们发现一共环可以有n个而q次询问,这样n*q=1e10了这肯定是不允许了,观察一下可以发现每个长度相同的环他的变换的同步的所以可以合并,而不同长度的环的数量显然只能有根号n级别个,那么合并就只需要 O ( q ∗ n ) O(q*\sqrt n) O(qn ),然后就能解出这道题了。

总时间复杂度 O ( q ∗ n ) + O ( n ∗ l o g n ) O(q*\sqrt n)+O(n*logn) O(qn )+O(nlogn)

提示点:因为要卷积很多次所以每次要清空数组,还有这题会报long long,FFT好像精度卡的好的话可以过,NTT的写法的话要找到一个1e18左右的模数可以查原根表或者写个暴力判原根。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 500007;
const ll p = 180143985094819841, G = 6;
int x,k;
bool vis[N];
ll p1[N],p2[N],xi[N];
vector<ll>ans[101000];
int n1,q;
ll limit = 1;//
ll L;//二进制的位数
ll RR[N];
ll a[N], b[N];ll qpow(ll a, ll b)
{ll res = 1;while(b) {if(b & 1) res =(__int128_t) res * a % p;a = (__int128_t)a * a % p;b >>= 1;}return res % p;
}ll inv(ll x) {return qpow(x, p - 2);}void NTT(ll *A, int type)
{for(int i = 0; i < limit; ++ i)if(i < RR[i])swap(A[i], A[RR[i]]);for(int mid = 1; mid < limit; mid <<= 1) {//原根代替单位根ll wn = qpow(G, (p - 1) / (mid * 2));if(type == -1) wn = qpow(wn, p - 2);for(int len = mid << 1, pos = 0; pos < limit; pos += len) {ll w = 1;for(int k = 0; k < mid; ++ k, w = ((__int128_t)w * wn) % p) {ll x = A[pos + k], y =(__int128_t) w * A[pos + mid + k] % p;A[pos + k] = ((__int128_t)x + y) % p;A[pos + k + mid] = ((__int128_t)x - y + p) % p;}}}if(type == -1) {ll limit_inv = inv(limit);//N的逆元(N是limit, 指的是2的整数幂)for(ll i = 0; i < limit; ++ i)A[i] = ((__int128_t)A[i] * limit_inv) % p;//NTT还是要除以n的,但是这里把除换成逆元了,inv就是n在模p意义下的逆元}
}
//多项式乘法
void poly_mul(ll *a, ll *b, int deg)
{for(limit = 1, L = 0; limit <= deg; limit <<= 1) L ++ ;for(ll i = 0; i < limit; ++ i) {RR[i] = (RR[i >> 1] >> 1) | ((i & 1) << (L - 1));}NTT(a, 1);NTT(b, 1);for(ll i = 0; i < limit; ++ i) a[i] = (__int128_t)a[i] * b[i] % p;NTT(a, -1);
}
int A[N];
int main(){scanf("%d%d",&n1,&q);for(int i=1;i<=n1;i++){scanf("%d",&A[i]);}for(int i=1;i<=n1;i++){if(!vis[i]){int noww=0;a[noww++]=i;vis[i]=true;for(int j=A[i];!vis[j];j=A[j]){a[noww++]=j;vis[j]=true;}for(int j=noww;j<=4*noww;j++){a[j]=b[j]=0;}for(int j=noww-1;j>=0;j--){b[j]=a[noww-1-j];}poly_mul(a, b, 2*noww-2);for(int j=0;j<noww;j++){p1[j]=a[j];}for(int j=0;j<noww-1;j++){a[j]=a[j]+p1[noww-2-j];}if (!ans[noww].size()) ans[noww].resize(noww);for(int j=0;j<noww;j++){ans[noww][j]+=a[(noww+j-1)%noww];}}}vector<int> si;for(int i=1;i<=n1;i++){if(ans[i].size()) si.push_back(i);}for(int i=1;i<=q;i++){int k;ll Ans=0;scanf("%d",&k);for(int j: si){Ans=Ans+ans[j][k%j];}printf("%lld\n",Ans);}return 0;
}

这篇关于2021icpc澳门 E-Pass the Ball!(NTT)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/315191

相关文章

【CTF Web】BUUCTF Upload-Labs-Linux Pass-13 Writeup(文件上传+PHP+文件包含漏洞+PNG图片马)

Upload-Labs-Linux 1 点击部署靶机。 简介 upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。 注意 1.每一关没有固定的通关方法,大家不要自限思维! 2.本项目提供的writeup只是起一个参考作用,希望大家可以分享出自己的通关思路

HDU 1556 Color the ball (树状数组-- 区间更新,单点求值)

OJ题目 :点这里~~ 与 单点更新,区间求值 稍有不同,需要理解注意。 AC_CODE int n;int num[100002];int lowbit(int x){return x&(-x);}int sum(int x){int ret = 0;while(x > 0){ret += num[x];x -= lowbit(x);}return ret;}void ad

Nginx location 和 proxy_pass 配置详解

概述 Nginx 配置中 location 和 proxy_pass 指令的不同组合方式及其对请求转发路径的影响。 配置效果 1. location 和 proxy_pass 都带斜杠 / location /api/ {proxy_pass http://127.0.0.1:8080/;} 访问地址:www.hw.com/api/upload转发地址:http://127.0.0.

Python控制流:循环控制(break, continue, pass)③

文章目录 前言1. 循环结构1.1 `for` 循环1.2 `while` 循环 2. 循环控制语句2.1 `break` 语句2.2 `continue` 语句2.3 `pass` 语句 3. 综合详细的例子:银行账户管理系统3.1 类和方法`BankAccount` 类 3.2 主函数 4. 循环控制语句的常见用法4.1 使用 `break` 终止无限循环4.2 使用 `continu

【CTF Web】BUUCTF Upload-Labs-Linux Pass-04 Writeup(文件上传+PHP+.htaccess绕过)

Upload-Labs-Linux 1 点击部署靶机。 简介 upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。 注意 1.每一关没有固定的通关方法,大家不要自限思维! 2.本项目提供的writeup只是起一个参考作用,希望大家可以分享出自己的通关思路

hdu1556--Color the ball

Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8883 Accepted Submission(s): 4542 Problem Description N个气球排成一排,从左到右依次编号为1

ZOJ 3904 Birthday Gift【NTT】

首先,我们知道的是, num1+num2=N num_1+num_2=N,其中 num1 num_1是Alice的盒子数, num2 num_2是Bob的盒子数。 那么 ans[N]=∑Alice(num1)×Bob(N−num1) ans[N]=\sum Alice(num_1)\times Bob(N-num1),明显是FFT的卷积形式。 接下来分析 Alice(num1) Alice(n

nginx中proxy_pass最后到底要不要加/

nginx中proxy_pass最后到底要不要加/ 在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url最后加/,表示绝对路径; 如果没有/,表示相对路径,把匹配的路径部分也给代理走,具体示例如下: url最后带/ location /test/ {proxy_pass http://$upstream/;} 请求地址http://$domainna

[实践篇]13.29 再来聊下Pass Through设备透传

写在前面 为什么要再聊天Pass Through? 因为在QNX + Linux Android的技术方案下,我们会遇到LA发生reboot或异常panic后,无法正常开机。而再次异常的原因确实最头疼的Memory Corruption。观察下来是由于一些DMA外设如使用UART的一些设备在重启或panic后,没有正常走Shutdown流程,导致Buffer仍然被使用。所以这里再进行一些总结。

解决nginx使用proxy_pass反向代理时,session cookie丢失的问题

今天在看sso(单点登录)时,看到了这篇文章,nginx反向代理解决cookie带不过去的问题,关键点是加上 proxy_cookie_path(路径转换),下面是正文: ------------------------------------------------------------------------------------------- 1. 如果只是host、端口转换,则co