3.15 模拟赛

T1

T2 小R的箱子

T3 绯红之王

题目大意:

已知数列$a$,求$\sum\limits_{i=1}^n {a_i}^k$

思路:

很久以前讲过的题,调了一年才搞出来

首先设$f_k=\sum\limits_{i=1}^n {a_i}^k$ , $g_k$表示对于所有$C_n^k$种选择的方法,$g_k=$所有方法内各个数相乘的和

例如数列中有四个数$a,b,c,d$ 则

$g_0=1$

$g_1=a+b+c+d$

$g_2=ab+ac+ad+bc+bd+cd$

$g_3=abc+abd+acd+bcd,g_4=abcd$

我们可以发现

$f_2=f_1 * g_1 - 2g_2$

$f_3=f_2 * g_1 - f_1* g_2 + 3g_3$

$f_4=f_3*g_1-f_2*g_2+f_1*g_3-4g_4$

发现下标为偶数的$g$都变成了其相反数,而且这是一个$f_0$在变化的分治$NTT$形式

那么我们将$f_0$设为0,在$cdq$到$l==r$时,再加上这个$n*g_n$贡献

现在考虑如何计算$g$数组,因为$g_i$是齐次轮换对称式 可以通过计算两部分再合并

例如$h_0=1,h_1=a+b+c,h_2=ab+ac+bc,h_3=abc$

$t_0=1,t_1=d+e+f,t_2=de+df+ed,t_3=def$

则$g_0=h_0*t_0=1$

$g_1=h_0*t_1+h_1*t_0$

$g_2=h_0*t_2+h_1*t_1+h_2*t_0$

$......$

这样可以维护一个类似线段树的结构来计算$g$,即一开始每个点有一个自己的多项式$1,a_i$

然后一层一层往上合并,计算出$g$后再用分治$NTT$来计算$f$

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 #include<set>
11 #define ll long long
12 #define db double
13 #define inf 2139062143
14 #define MAXN 800100
15 #define MOD 998244353
16 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
17 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
18 #define ren for(register int i=fst[x];i;i=nxt[i])
19 #define pb(i,x) vec[i].push_back(x)
20 #define pls(a,b) (1LL*a%MOD+b%MOD+MOD)%MOD
21 #define mns(a,b) (1LL*a%MOD-b%MOD+MOD)%MOD
22 #define mul(a,b) ((ll)(1LL*(a))%MOD*(b)%MOD)%MOD
23 using namespace std;
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();}
28     while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();}
29     return x*f;
30 }
31 int n,rev[MAXN],l2[MAXN],pw[MAXN],A[MAXN],B[MAXN],aa[MAXN];
32 int g[MAXN],f[MAXN];
33 vector<int> vec[MAXN];
34 int q_pow(int bas,int t,int res=1)
35 {
36     for(;t;bas=mul(bas,bas),t>>=1)
37         if(t&1) res=mul(res,bas);return res;
38 }
39 void ntt(int *a,int n,int f)
40 {
41     rep(i,0,n-1) if(i<rev[i]) swap(a[i],a[rev[i]]);
42     for(int i=1;i<n;i<<=1)
43     {
44         int wn=pw[i<<1];if(f==-1) wn=q_pow(wn,MOD-2);
45         for(int j=0;j<n;j+=i<<1)
46         {
47             int w=1,x,y;
48             for(int k=0;k<i;k++,w=mul(w,wn))
49                 x=a[k+j],y=mul(a[i+j+k],w),a[j+k]=pls(x,y),a[i+j+k]=mns(x,y);
50         }
51     }
52     if(f==1) return ;int nv=q_pow(n,MOD-2);
53     rep(i,0,n-1) a[i]=mul(a[i],nv);
54 }
55 void solve(int *a,int *b,int lmt)
56 {
57     ntt(a,lmt,1);ntt(b,lmt,1);rep(i,0,lmt-1) a[i]=mul(a[i],b[i]);
58     ntt(a,lmt,-1);
59 }
60 void Div(int l,int r,ll lmt=0)
61 {
62     if(l==r) return ;int mid=(l+r)>>1,lg;
63     Div(l,mid);Div(mid+1,r);lg=l2[r-l+1]+1,lmt=1<<lg;
64     rep(i,0,lmt-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)),A[i]=B[i]=0;
65     rep(i,0,vec[l].size()-1) A[i]=vec[l][i];
66     rep(i,0,vec[mid+1].size()-1) B[i]=vec[mid+1][i];
67     solve(A,B,lmt);
68     vec[l].clear();vec[mid+1].clear();
69     rep(i,0,lmt-1) vec[l].push_back(A[i]);
70 }
71 void cdq(int l,int r)
72 {
73     if(l==r) {f[l]=pls(f[l],mul(g[l],l));return ;}
74     int mid=l+r>>1,lmt=r-l+1;cdq(l,mid);
75     int t=l2[lmt]+1;lmt=1<<t;
76     rep(i,0,lmt-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(t-1)),A[i]=B[i]=0;
77     rep(i,l,mid) A[i-l]=f[i];rep(i,1,r-l) B[i-1]=g[i];
78     solve(A,B,lmt);rep(i,mid+1,r) f[i]=pls(f[i],A[i-l-1]);
79     cdq(mid+1,r);
80 }
81 int main()
82 {
83     n=read();rep(i,1,n) aa[i]=read();rep(i,2,n<<2) l2[i]=l2[i>>1]+1;
84     rep(i,1,n<<2) pw[i]=q_pow(3,(MOD-1)/i);
85     rep(i,1,n) vec[i].push_back(1),vec[i].push_back(aa[i]);
86     Div(1,n);rep(i,0,n) g[i]=vec[1][i];
87     rep(i,0,n) if(!(i&1)) g[i]=-g[i];
88     cdq(0,n);rep(i,1,n) printf("%d\n",f[i]);
89 }

原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10539856.html

时间: 2024-11-02 10:02:27

3.15 模拟赛的相关文章

8.15模拟赛

T1.第K小数[问题描述]有两个正整数数列,元素个数分别为N和M.从两个数列中分别任取一个数相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少.[输入格式]输入文件名为number.in.输入文件包含三行.第一行为三个正整数N,M和K.第二行为N个正整数,表示第一个数列.第三行为M个正整数,表述第二个数列.[输出格式]输出文件名为number.out.输出文件包含一行,一个正整数表示第K小数.[输入输出样例1 1 ]number.in 2 3 41 22 1 3 number.o

9.15模拟赛

T1 np问题 题目描述 LYK喜欢研究一些比较困难的问题,比如np问题. 这次它又遇到一个棘手的np问题.问题是这个样子的:有两个数n和p,求n的阶乘对p取模后的结果. LYK觉得所有np问题都是没有多项式复杂度的算法的,所以它打算求助即将要参加noip的你,帮帮LYK吧! 输入输出格式 输入格式: 输入一行两个整数n,p. 输出格式: 输出一行一个整数表示答案. 输入输出样例 输入样例#1: 3 4 输出样例#1: 2 说明 对于20%的数据:n,p<=5. 对于40%的数据:n,p<=1

2017/9/15模拟赛

游戏(game) [问题描述] 小R和小H在玩某个双人联机小游戏,一开始两人所操控的角色各有1点力量值,而在游戏中,每通过一关都会掉落一些力量强化道具.奇怪的是,明明是双人小游戏,每关却都会掉落3个相同的力量强化道具,于是两人决定每关每人先拿一个,剩下一个猜拳决定给谁.一个力量强化道具能使一个角色的力量值变为原来的若干整数倍,同一关卡掉落的道具倍率都相同,而不同的关卡可能不同.小R从攻略上找到了一些会产生特殊效果的力量值组合,他想知道哪些组合是按他们的道具分配方式有可能在通过某关时达成的. [输

10月15日模拟赛题解

10月15日模拟赛题解 A 树 Description 给定一棵 \(n\) 个节点的树,每个节点有两个参数 \(a,~b\),对于每个节点,求子树中参数为 \(b\) 的所有节点的 \(a\) 之和 Limitations \(100\%\) \(1 \leq b \leq n \leq 10^5,~a \leq 1000\) \(60\%\) \(1 \leq b,n\leq 1000\) \(30\%\) \(1 \leq b, n \leq 10\) Solution 对于 \(30\%

8月15日模拟赛小结

今天的模拟赛是三道陈老师的题. 在 10:48 左右已经都能拿到了. 然后我觉得 T3 的蒙特卡洛算法不太稳, 于是调大参数. 本地不开 O2 需要 5s 左右, 开 O2 测需要 2s , 而时限是 3s . 我想着 XSY 也开了 O2 , 所以稳了. 结果比赛结束 T3 全部 TLE ..... 中途还犯了一次A题代码交到B题的错误. ZJT大爷说我从第 2 调到了倒数第 1 , QAQ . 得出结论: ① 很多评测机可能很辣鸡. 所以如果对于随机化算法之类的, 能开大迭代次数的标准是:

【BZOJ】【2741】【FOTILE模拟赛】L

可持久化Trie+分块 神题……Orz zyf & lyd 首先我们先将整个序列搞个前缀异或和,那么某一段的异或和,就变成了两个数的异或和,所以我们就将询问[某个区间中最大的区间异或和]改变成[某个区间中 max(两个数的异或和)] 要是我们能将所有[l,r]的答案都预处理出来,那么我们就可以O(1)回答了:然而我们并不能. 一个常见的折中方案:分块! 这里先假设我们实现了一个神奇的函数ask(l,r,x),可以帮我们求出[l,r]这个区间中的数,与x最大的异或值. 我们不预处理所有的左端点,我

10.30 NFLS-NOIP模拟赛 解题报告

总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没码QAQ 现在我来写解题报告了,有点饿了QAQ.. 第一题 题目 1: 架设电话线 [Jeffrey Wang, 2007] 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务,于 是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线.新的电话线架设 在已有的N(2 <=

bzoj 2741: 【FOTILE模拟赛】L 分塊+可持久化trie

2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1116  Solved: 292[Submit][Status] Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r. 为了体现在线操作,对于一个询问(x,y):

【题解】PAT团体程序设计天梯赛 - 模拟赛

由于本人愚笨,最后一题实在无力AC,于是只有前14题的题解Orz 总的来说,这次模拟赛的题目不算难,前14题基本上一眼就有思路,但是某些题写起来确实不太容易,编码复杂度有点高~ L1-1 N个数求和 设计一个分数类,重载加法运算符,注意要约分,用欧几里得算法求个最大公约数即可. 1 #include <cstdio> 2 3 long long abs(long long x) 4 { 5 return x < 0 ? -x : x; 6 } 7 8 long long gcd(long