简单的数据结构题(多项式、拉格朗日插值、线段树)
簡單的數據結構題
首先考慮計算要求的式子,不妨設l=1,r=nl=1,r=nl=1,r=n。
∑i=1naik∏j=?i1?aiajai?aj\sum_{i=1}^{n}a_i^k\prod_{j\not=i}\frac{1-a_ia_j}{a_i-a_j}∑i=1n?aik?∏j?=i?ai??aj?1?ai?aj??
=∑i=1naik∏j=?i1ai?aj∏j=?i(1?aiaj)=\sum_{i=1}^{n}a_i^k\prod_{j\not=i}\frac{1}{a_i-a_j}\prod_{j\not=i}(1-a_ia_j)=∑i=1n?aik?∏j?=i?ai??aj?1?∏j?=i?(1?ai?aj?)
=∑i=1naik∏j=?i1ai?aj∑l=0n?1[xn?1?l]∏j=?i(x?aiaj)=\sum_{i=1}^{n}a_i^k\prod_{j\not=i}\frac{1}{a_i-a_j}\sum_{l=0}^{n-1}[x^{n-1-l}]\prod_{j\not=i}(x-a_ia_j)=∑i=1n?aik?∏j?=i?ai??aj?1?∑l=0n?1?[xn?1?l]∏j?=i?(x?ai?aj?)
=∑i=1naik∏j=?i1ai?aj∑l=0n?1ail[xn?1?l]∏j=?i(x?aj)=\sum_{i=1}^{n}a_i^k\prod_{j\not=i}\frac{1}{a_i-a_j}\sum_{l=0}^{n-1}a_i^l[x^{n-1-l}]\prod_{j\not=i}(x-a_j)=∑i=1n?aik?∏j?=i?ai??aj?1?∑l=0n?1?ail?[xn?1?l]∏j?=i?(x?aj?)
=∑l=0n?1∑i=1naik+l∏j=?i1ai?aj[xn?1?l]∏j=?i(x?aj)=\sum_{l=0}^{n-1}\sum_{i=1}^{n}a_i^{k+l}\prod_{j\not=i}\frac{1}{a_i-a_j}[x^{n-1-l}]\prod_{j\not=i}(x-a_j)=∑l=0n?1?∑i=1n?aik+l?∏j?=i?ai??aj?1?[xn?1?l]∏j?=i?(x?aj?)
=∑l=0n?1∑i=1n[xn?1?l](aik+l∏j=?i1ai?aj)x0∏j=?i(x?aj)=\sum_{l=0}^{n-1}\sum_{i=1}^{n}[x^{n-1-l}](a_i^{k+l}\prod_{j\not=i}\frac{1}{a_i-a_j})x^0\prod_{j\not=i}(x-a_j)=∑l=0n?1?∑i=1n?[xn?1?l](aik+l?∏j?=i?ai??aj?1?)x0∏j?=i?(x?aj?)
=∑l=0n?1∑i=1n[xn?1?l]aik+l∏j=?ix?ajai?aj=\sum_{l=0}^{n-1}\sum_{i=1}^{n}[x^{n-1-l}]a_i^{k+l}\prod_{j\not=i}\frac{x-a_j}{a_i-a_j}=∑l=0n?1?∑i=1n?[xn?1?l]aik+l?∏j?=i?ai??aj?x?aj??
=∑l=0n?1[xn?1?l]∑i=1naik+l∏j=?ix?ajai?aj=\sum_{l=0}^{n-1}[x^{n-1-l}]\sum_{i=1}^{n}a_i^{k+l}\prod_{j\not=i}\frac{x-a_j}{a_i-a_j}=∑l=0n?1?[xn?1?l]∑i=1n?aik+l?∏j?=i?ai??aj?x?aj??
根據拉格朗日插值:
f(x)f(x)f(x)是一個過點(x1,y1),(x2,y2),...,(xn,yn)的函數(x_1,y_1),(x_2,y_2),...,(x_n,y_n)的函數(x1?,y1?),(x2?,y2?),...,(xn?,yn?)的函數
記M=∏i=1n(x?xi)M=\prod_{i=1}^{n}(x-x_i)M=∏i=1n?(x?xi?),則
f(x)≡∑i=1nyi∏j=?ix?xjxi?xj(modM)f(x)\equiv \sum_{i=1}^{n}y_i\prod_{j\not=i}\frac{x-x_j}{x_i-x_j}(mod\space M)f(x)≡∑i=1n?yi?∏j?=i?xi??xj?x?xj??(mod?M)
函數f(x)=xk+lf(x)=x^{k+l}f(x)=xk+l過點(a1,a1k+l),(a2,a2k+l),...,(an,ank+l)(a_1,a_1^{k+l}),(a_2,a_2^{k+l}),...,(a_n,a_n^{k+l})(a1?,a1k+l?),(a2?,a2k+l?),...,(an?,ank+l?)
∴xk+l≡∑i=1naik+l∏j=?ix?ajai?aj(mod(x?a1)(x?a2)...(x?an))\therefore x^{k+l}\equiv\sum_{i=1}^{n}a_i^{k+l}\prod_{j\not=i}\frac{x-a_j}{a_i-a_j}(mod\space(x-a_1)(x-a_2)...(x-a_n))∴xk+l≡∑i=1n?aik+l?∏j?=i?ai??aj?x?aj??(mod?(x?a1?)(x?a2?)...(x?an?))
∴原式=∑l=0n?1[xn?1?l](xk+lmod(x?a1)(x?a2)...(x?an))\therefore原式=\sum_{l=0}^{n-1}[x^{n-1-l}](x^{k+l}\mod(x-a_1)(x-a_2)...(x-a_n))∴原式=∑l=0n?1?[xn?1?l](xk+lmod(x?a1?)(x?a2?)...(x?an?))
注意到0≤k≤20\leq k\leq20≤k≤2,且l≤n?1l\leq n-1l≤n?1,所以k+l≥nk+l\geq nk+l≥n的情況不多,分類討論即可:
1.若k+l≤n?1k+l\leq n-1k+l≤n?1(xk+lx^{k+l}xk+l的次數低于modmodmod的多項式):
原式=∑l=1n?1[xn?1?l]xk+l=∑l=1n?1[n?1?l=k+l]原式=\sum_{l=1}^{n-1}[x^{n-1-l}]x^{k+l}=\sum_{l=1}^{n-1}[n-1-l=k+l]原式=∑l=1n?1?[xn?1?l]xk+l=∑l=1n?1?[n?1?l=k+l]
解得l=n?k?12l=\frac{n-k-1}{2}l=2n?k?1?
則當n?k?1≡0(mod2)n-k-1\equiv 0(mod\space 2)n?k?1≡0(mod?2)且0≤n?k?10\leq n-k-10≤n?k?1時原式為1,否則為0,
即當n?k?1≡1(mod2)n-k-1\equiv1(mod\space 2)n?k?1≡1(mod?2)或n=1,k=2n=1,k=2n=1,k=2時原式為0,否則為1
2.若k+l≥nk+l\geq nk+l≥n:
∵l≤n?1\because l\leq n-1∵l≤n?1 ∴k≥1\therefore k\geq1∴k≥1
2.1若k=1k=1k=1:
此時有l=n?1l=n-1l=n?1
原式=[x0](xnmod(x?a1)(x?a2)...(x?an))原式=[x^0](x^n\mod(x-a_1)(x-a_2)...(x-a_n))原式=[x0](xnmod(x?a1?)(x?a2?)...(x?an?))
=[x0](xn?(x?a1)(x?a2)...(x?an))=[x^0](x^n-(x-a_1)(x-a_2)...(x-a_n))=[x0](xn?(x?a1?)(x?a2?)...(x?an?))
=(?1)n+1a1a2...an=(-1)^{n+1}a_1a_2...a_n=(?1)n+1a1?a2?...an?
2.2若k=2k=2k=2:
此時有l=n?2或l=n?1l=n-2或l=n-1l=n?2或l=n?1
2.2.1若 l=n?2l=n-2l=n?2:
∵l≥0\because l\geq0∵l≥0 ∴n=?1\therefore n\not=1∴n?=1
原式=[x1](xnmod(x?a1)(x?a2)...(x?an))原式=[x^1](x^n\mod(x-a_1)(x-a_2)...(x-a_n))原式=[x1](xnmod(x?a1?)(x?a2?)...(x?an?))
=[x1](xn?(x?a1)(x?a2)...(x?an))=[x^1](x^n-(x-a_1)(x-a_2)...(x-a_n))=[x1](xn?(x?a1?)(x?a2?)...(x?an?))
=(?1)n∑i=1n∏j=?iaj=(-1)^n\sum_{i=1}^{n}\prod_{j\not=i}a_j=(?1)n∑i=1n?∏j?=i?aj?
2.2.2若 l=n?1l=n-1l=n?1:
原式=[x0](xn+1mod(x?a1)(x?a2)...(x?an))原式=[x^0](x^{n+1}\mod(x-a_1)(x-a_2)...(x-a_n))原式=[x0](xn+1mod(x?a1?)(x?a2?)...(x?an?))
=[x0](xn+1?(x+a1+a2+...+an)?大除法得出(x?a1)(x?a2)...(x?an))=[x^0](x^{n+1}-\begin{matrix}\underbrace{(x+a_1+a_2+...+a_n)}\\大除法得出\end{matrix}(x-a_1)(x-a_2)...(x-a_n))=[x0](xn+1?(x+a1?+a2?+...+an?)?大除法得出?(x?a1?)(x?a2?)...(x?an?))
=(?1)n+1∑i=1nai∏j=1naj=(-1)^{n+1}\sum_{i=1}^{n}a_i\prod_{j=1}^{n}a_j=(?1)n+1∑i=1n?ai?∏j=1n?aj?
當n=1,k=2n=1,k=2n=1,k=2時,兩處的特判可以相互抵消,于是可以不需要特判。
于是只要維護∑i=1nai\sum_{i=1}^{n}a_i∑i=1n?ai? ,∏i=1nai\prod_{i=1}^{n}a_i∏i=1n?ai? ,∑i=1n∏j=?iaj\sum_{i=1}^{n}\prod_{j\not=i}a_j∑i=1n?∏j?=i?aj?,在區間乘的操作下用線段樹解決
#include<iostream> #include<cstdio> using namespace std; const int mod=998244353; const int N=300010; int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f; } struct Node{int sum,pro,ans;Node(){sum=0;pro=1;ans=0;}Node(int a,int b,int c){sum=a,pro=b,ans=c;} }t[N<<2]; int n,m,a[N],laz[N<<2]; int add(int a,int b){return a+b>=mod?a+b-mod:a+b;} int dec(int a,int b){return a-b<0?a-b+mod:a-b;} int mul(int a,int b){return 1ll*a*b%mod;} int power(int a,int b){int res=1;while(b){if(b&1) res=mul(res,a);a=mul(a,a);b>>=1;}return res; } Node merge(Node a,Node b){Node c;c.sum=add(a.sum,b.sum);c.pro=mul(a.pro,b.pro);c.ans=add(mul(a.ans,b.pro),mul(a.pro,b.ans));return c; } void pushup(int u){t[u]=merge(t[u<<1],t[u<<1|1]); } void build(int u,int l,int r){laz[u]=1;if(l==r){t[u]=Node(a[l],a[l],1);return;}int mid=(l+r)>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u); } void modify(int u,int l,int r,int x){t[u].sum=mul(t[u].sum,x);t[u].pro=mul(t[u].pro,power(x,r-l+1));t[u].ans=mul(t[u].ans,power(x,r-l));laz[u]=mul(laz[u],x); } void pushdown(int u,int l,int r){if(laz[u]!=1){int mid=(l+r)>>1;modify(u<<1,l,mid,laz[u]);modify(u<<1|1,mid+1,r,laz[u]);laz[u]=1;} } void update(int u,int l,int r,int a,int b,int x){if(a<=l&&r<=b){modify(u,l,r,x);return;}pushdown(u,l,r);int mid=(l+r)>>1;if(a<=mid) update(u<<1,l,mid,a,b,x);if(b>mid) update(u<<1|1,mid+1,r,a,b,x);pushup(u); } Node query(int u,int l,int r,int a,int b){if(a<=l&&r<=b) return t[u];pushdown(u,l,r);int mid=(l+r)>>1;Node res=Node(0,1,0);if(a<=mid) res=merge(res,query(u<<1,l,mid,a,b));if(b>mid) res=merge(res,query(u<<1|1,mid+1,r,a,b));return res; } int main(){n=read();m=read();for(int i=1;i<=n;i++) a[i]=read();build(1,1,n);int opt,l,r,k;while(m--){opt=read();l=read();r=read();k=read();if(opt==1)update(1,1,n,l,r,k);else{int d=r-l+1,ans=0;if(!((d-k-1)&1)) ans++;Node now=query(1,1,n,l,r);if(k==1){if(d&1) ans=add(ans,now.pro);else ans=dec(ans,now.pro);}if(k==2){if(!(d&1)) ans=add(ans,now.ans);else ans=dec(ans,now.ans);if(d&1) ans=add(ans,mul(now.sum,now.pro));else ans=dec(ans,mul(now.sum,now.pro));}printf("%d\n",ans);}}return 0; }總結
以上是生活随笔為你收集整理的简单的数据结构题(多项式、拉格朗日插值、线段树)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 路由器桥接有线连接方式有哪几种两个路由器
- 下一篇: 如何设置Macbook触控板轻按操作如何