题目大意:给出n个地点和q个询问。其中每个地点有距离和权值,每个询问给出l,r,k,表示在[l,r]区间内不取最小点的情况下任取k个,求所有情况权值之积之和(n,q<=1e5,k<=6)。
能看出来是区间操作,先考虑树状数组,发现维护比较难。于是用线段树维护。
每个节点记录7个值,分别为minv和不算minv任取1~6个所得值。dalao的正解用了RMQ+容斥,但我都没用。
#include<cstdio> #include<algorithm> using namespace std; #define N 100050 #define ui unsigned int int n,Q; struct pla { int d,v; }p[N]; bool cmp(pla a,pla b) { return a.d<b.d; } struct segtree { ui mn; ui v[8]; }tr[4*N]; segtree operator * (segtree s0,segtree s1) { segtree ret; for(int i=1;i<=6;i++) { ret.v[i]=s0.v[i]+s1.v[i]; for(int j=1;j<i;j++)ret.v[i]+=s0.v[j]*s1.v[i-j]; } ret.mn = min(s0.mn,s1.mn); ui mx = max(s0.mn,s1.mn); for(int i=6;i>=2;i--) { ret.v[i]+=ret.v[i-1]*mx; } ret.v[1]+=mx; return ret; } void update(int u) { tr[u] = tr[u<<1] * tr[u<<1|1]; } void build(int l,int r,int u) { if(l==r) { tr[u].mn=(ui)p[l].v; return ; } int mid = (l+r)>>1; build(l,mid,u<<1); build(mid+1,r,u<<1|1); update(u); } segtree query(int l,int r,int u,int ql,int qr) { if(l==ql&&r==qr)return tr[u]; int mid = (l+r)>>1; if(ql>mid)return query(mid+1,r,u<<1|1,ql,qr); else if(qr<=mid) return query(l,mid,u<<1,ql,qr); else { segtree s0=query(l,mid,u<<1,ql,mid); segtree s1=query(mid+1,r,u<<1|1,mid+1,qr); segtree ret = s0 * s1; return ret; } } ui jc[8]; int mi[24]; int findl(int d) { int a = n; for(int i=20;i>=0;i--) { if(a-mi[i]<=0)continue; if(p[a-mi[i]].d>=d)a-=mi[i]; } return a; } int findr(int d) { int a = 1; for(int i=20;i>=0;i--) { if(a+mi[i]>n)continue; if(p[a+mi[i]].d<=d)a+=mi[i]; } return a; } int main() { // freopen("c.in","r",stdin); // freopen("c.out","w",stdout); scanf("%d%d",&n,&Q); jc[1]=1,jc[2]=2,jc[3]=6,jc[4]=24,jc[5]=120,jc[6]=720; mi[0]=1; for(int i=1;i<=20;i++)mi[i]=mi[i-1]<<1; for(int i=1;i<=n;i++)scanf("%d",&p[i].d); for(int i=1;i<=n;i++)scanf("%d",&p[i].v); sort(p+1,p+1+n,cmp); build(1,n,1); for(int ll,rr,l,r,k,i=1;i<=Q;i++) { scanf("%d%d%d",&ll,&rr,&k); l = findl(ll); r = findr(rr); if(l>r) { printf("0 "); continue; } segtree ans; ans = query(1,n,1,l,r); printf("%u ",ans.v[k]*jc[k]); } fclose(stdin); fclose(stdout); return 0; }