【CQOI2015】多项式题解 (NKOJ3252)

再次感谢Wikipedia提供公式支撑。

题面:Here

这道题其实很水,坑点在高精度。

给定 $F(x)=\sum^n_{k=0}a_kx^k=\sum^n_{k=0}b_k(x-t)^k$, 求给定$b_m$。

想都不想就是$F(x)$在$x=t$处的Taylor展开

\begin{align}F(x)=\sum^n_{k=0}\frac{F^{(k)}(t)}{k!}(x-t)^k\end{align}

易知$b_m=\frac{F^{(m)}\ \ (t)}{m!}$, 而容易得到$\frac{F^{(m)}\ \ (t)}{m!}=\sum^{n-m}_{k=0}(^{m+k}_{k})a_{m+k}t^k$,

至于{$a_k$},因为$mod\ 3389$意义下的数是有限的,显然有循环节,跑一遍就知道$a_k=a_{k\ mod\ 3388}$, 剩下的就只剩下写个高精度乱搞了。

(然而自己过于菜,写个高精度调一下午。。。

(分段一定1e9!!!

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a;
const int MOD=1e9;
struct Big {
	ll S[10000],T,cur;
	void Input() {
		string s;cin>>s;int i,t,l=s.size();
		for(i=0;i<l;i++)
			t=(l-i-1)/9,S[t]=S[t]*10+s[i]-48,T=T*10+s[i]-48,T%=3388;
		cur=(l-1)/9;while(cur>0&&S[cur]==0) cur--;
	}
	void Divide(int k) {
		for(int i=cur;i>0;i--) {
			S[i-1]+=S[i]%k*MOD;S[i]/=k;
			if(S[cur]==0) cur--;
		} S[0]/=k;
	}
	void Add(int k) {
		S[0]+=k;int i=0;
		while(S[i]>=MOD) S[i+1]+=S[i]/MOD,S[i++]%=MOD;
		if(S[cur+1]) cur++;
	}
	void Add(const Big& o) {
		int i,r=max(o.cur,cur);
		for(i=0;i<=r;i++) {
			S[i]+=o.S[i];
			if(S[i]>=MOD) S[i+1]+=S[i]/MOD,S[i]%=MOD;
		} cur=r+5;while(cur>0&&S[cur]==0) cur--;
	}
	void Multiply(const Big& o,Big& E) {
		int i,j;memset(&E,0,sizeof(E));
		for(i=0;i<=cur;i++)
		for(j=0;j<=o.cur;j++) {
			E.S[i+j]+=S[i]*o.S[j];
			if(E.S[i+j]>=MOD) {
				E.S[i+j+1]+=E.S[i+j]/MOD;
				E.S[i+j]%=MOD;
			}
		}
		E.cur=cur+o.cur+5;
		while(E.S[E.cur]==0) E.cur--;
	}
	void Print() {
		printf("%lld",S[cur]);
		ll i,k;
		for(i=cur-1;i>=0;i--) {
			k=MOD/10;
			while(k>S[i]) putchar(‘0‘),k/=10;
			if(k) printf("%lld",S[i]);
		}
	}
} N,M,J[10],T[2],R[2],Q,P[2],ANS;
int K,k,i,j;
int main() {
	N.Input();J[1].Input();M.Input();K=N.T-M.T;K+=K<0?3388:0;
	a=1;for(i=1;i<=M.T;i++) a=(1234*a+5678)%3389;
//	cout<<N.T<<‘ ‘<<M.T<<endl;
	ANS.Add(a);T[0].S[0]=1;
//	N.Print();puts("");
//	J[1].Print();puts("");
//	M.Print();puts("");
	for(k=1;k<=K;k++) {
		M.Add(1);
//		M.Print();puts("");
		T[k-1&1].Multiply(M,T[k&1]);
//		T[k].Print();
		a=(1234*a+5678)%3389;
		Q.S[0]=a;
		T[k&1].Divide(k);//T[k].Print();
		T[k&1].Multiply(Q,R[k&1]);
		if(k<K) J[k].Multiply(J[1],J[k+1]);
		J[k].Multiply(R[k&1],P[k&1]);
		ANS.Add(P[k&1]);
	}
	ANS.Print();
//	N.Input();M.Input();
//	N.Multiply(M,ANS);
//	ANS.Print();
}

代码风格过于丑,请自动忽略各种调试语句。

时间: 2025-01-15 19:25:32

【CQOI2015】多项式题解 (NKOJ3252)的相关文章

BZOJ 3933 CQOI2015 多项式 高精度

题目大意戳这里 用x替换式子中的x-t得到: ∑nk=0ak(x+t)k=∑nk=0bkxk 于是可以得到: bm=∑nk=mCk?mktk?mak=∑n?mi=0Cim+itiam+i 其中ai=(209?1234i mod 3388+3181) mod 3389 然后...出题人我*尼玛... #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> usi

CQOI2015 后3题解题报告

这个嘛= =,CQOI我只做了后面3题(前面两题老师还没考就还不敢写= =)说一下被虐报告吧= = T3:[CQOI2015]任务查询系统 描述:戳我~~~ 这道题首先很明显是道裸的数据结构题啦.首先他要求在线,那么按顺序建个函数式线段树就行啦 自己太弱调了好久= = CODE: 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #inclu

【题解】CodeChef - TREDEG (prufer+生成函数+多项式exp)

[题解]CodeChef - TREDEG (prufer+生成函数+多项式exp) 好毒瘤的数据范围... 先转prufer,现在问题就变成了我要生成一个\(n-2\)长度的序列,每一种序列的权值定义为每种数的\(\prod\)(每种数出现个数+1),可以直接使用指数型生成函数生成,具体的: \[ (\sum_{i=0} {i+1\over i!}x^i)^n[x^{n-2}](n-2)! \] 这个就生成这个序列的答案了.用exp搞个快速幂就完事了. 最终答案的式子 \[ (\sum_{i=

PAT甲题题解-1009. Product of Polynomials (25)-多项式相乘

多项式相乘 注意相乘结果的多项式要开两倍的大小!!! #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string.h> using namespace std; //两个多项式相乘 const int maxn=1000+5; int k; //原本定义个exp导致编译错误,没想到定义成exp1.exp2也会编译错误,

BZOJ3932:[CQOI2015]任务查询系统——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=3932 题面源于洛谷 题目描述 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向查询系统询问,第Xi秒正在运行的任务中,

[bzoj3932][CQOI2015]任务查询系统-题解[主席树][权值线段树]

Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行 ),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向 查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个 )的优先级之和是多少.特别的,如

BZOJ3930:[CQOI2015]选数——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=3930 https://www.luogu.org/problemnew/show/P3172#sub 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究.然而他很快发现工作量太大了,于是向你寻求帮助.你的任务很简单,小z会告诉你一个整数K,你需要回答他最

洛谷4238:【模板】多项式求逆——题解

https://www.luogu.org/problemnew/show/P4238 如题所示,对998244353取模. 板子没啥好说的. 讲解看这位大佬:http://blog.miskcoo.com/2015/05/polynomial-inverse #include<cstdio> #include<cctype> #include<cstring> #include<vector> #include<cmath> #include&

【题解】CQOI2015选数

这题做的时候接连想错了好多次……但是回到正轨上之后依然是一个套路题.(不过这题好像有比莫比乌斯反演更好的做法,莫比乌斯反演貌似是某种能过的暴力ヽ(´ー`)┌)不过能过也就行了吧哈哈. 首先我们把数字的范围要进行缩小:最大公约数为 \(K\) 那自然所有选出来的数都必须是 \(K\) 的倍数.所以我们改选数为选择是 \(K\) 的多少倍.然后由于是最大公约数,所以选出来的这些数必须最大公约数等于\(1\).实际上多个数的最大公约数\( = 1\)完全可以和两个数的最大公约数 \( = 1\) 用一