1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #define N 100010 6 using namespace std; 7 int n,Q,l,r,k; 8 unsigned int f[N*4][7],g[7],jc[7],p[7]; 9 struct edge{ int d,v; }a[N]; 10 bool cmp(edge a,edge b) { return a.d<b.d; } 11 void work(unsigned int*x,unsigned int*y,unsigned int*k) 12 { 13 if (x[7]>y[7]) swap(x,y); 14 if (!x[7]) for (int i=0;i<=7;i++) k[i]=y[i]; 15 else 16 { 17 memset(p,0,sizeof(p)),p[0]=1; 18 for (int i=1;i<=6;i++) 19 { 20 for (int j=0;j<=i;j++) p[i]+=x[j]*y[i-j]; 21 for (int j=0;j<i;j++) p[i]+=x[j]*y[i-j-1]*y[7]; 22 } 23 p[7]=x[7]; for (int i=0;i<=7;i++) k[i]=p[i]; 24 } 25 } 26 void build(int d,int l,int r) 27 { 28 f[d][0]=1; 29 if (l==r) { f[d][7]=a[l].v; return; } 30 int mid=l+r>>1; 31 build(d*2,l,mid),build(d*2+1,mid+1,r),work(f[d*2],f[d*2+1],f[d]); 32 } 33 void Query(int d,int l,int r,int L,int R) 34 { 35 if (a[l].d>R||a[r].d<L) return; 36 if (L<=a[l].d&&a[r].d<=R) { work(f[d],g,g); return; } 37 int mid=l+r>>1; 38 Query(d*2,l,mid,L,R),Query(d*2+1,mid+1,r,L,R); 39 } 40 int main() 41 { 42 scanf("%d%d",&n,&Q); 43 for (int i=1;i<=n;i++) scanf("%d",&a[i].d); 44 for (int i=1;i<=n;i++) scanf("%d",&a[i].v); 45 jc[0]=1; for (int i=1;i<=6;i++) jc[i]=jc[i-1]*i; 46 sort(a+1,a+n+1,cmp),build(1,1,n); 47 while (Q--) scanf("%d%d%d",&l,&r,&k),memset(g,0,sizeof(g)),g[0]=1,Query(1,1,n,l,r),printf("%lld\n",g[k]*jc[k]); 48 }
[线段树][数学] Jzoj P4237 Melancholy
原文:https://www.cnblogs.com/Comfortable/p/10331534.html