题目是保密的,所以我只写题解了,先%曹力升大爷一发。
设
ci,j
表示前
i
个数,取
比如
{a1,a2,a3}
这个集合,
c3,2=a1∗a2+a1∗a3+a2∗a3
,也就是说我们求出来的答案还要乘一个阶乘就是最终答案了。
考虑求区间
[l,r]
取
k
个的答案
getAns(l,r,k)=cr,k−cl−1,k−∑i=1k−1(getAns(l,r,k−i)×cl−1,i)
前面两项应该很显然,先减掉因子都不在
[l,r]
里面的,然后那个和式处理的就是因子两边都有的情况,先枚举
l
左边的因子有多少个,然后(乘法分配律。。。。(大雾 %zqf) )
还有一个蛋疼的东西,那就是处理最小值,还是一样的,先找出最小值的位置,线段,RMQ什么的都可以。
然后就是要减掉因子包含最小值的乘积啦,记这些乘积的和为
F
,最小值的位置为
则
F=∑i=0k−1(getAns(l,p−1,i)×getAns(p+1,r,k−i−1)×min)
减掉
F
<script type="math/tex" id="MathJax-Element-17">F</script>,乘个阶乘,完事。
今天月考雪崩。。。。。。(%zqf)
之前写了个线段树,超时了,改了RMQ还超时,后来发现数组开小了,取六个数数组开成了6也是醉了,开7好吧。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define X first
#define Y second
#define MP make_pair
#define pii pair<int,int>
#define LL unsigned int
#define pll pair<LL,LL>
#define DEBUG(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
const int MAXN=1e5+10,MAXNODE=4*MAXN;
void Read(LL& x)
{
x=0;bool flag=0;char c;
while(c=getchar())
{
if(c>='0'&&c<='9')x*=10,x+=c-'0',flag=1;
else if(flag)break;
}
}
template <typename T>
void write(T v) {
static int st[30];
int tp = 0;
T t = v;
if(t < 0)
putchar('-'), t = -t;
while(t)
st[++tp] = t % 10, t /= 10;
if(tp == 0)
putchar('0');
while(tp)
putchar(st[tp--] + '0');
}
LL zqf,c[MAXN][7],n,q,l,r,k,fac[7]={0,1,2,6,24,120,720},f[32][MAXN],t[32][MAXN];
pll planet[MAXN];
void pre()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=min(n,(LL)6);j++)
{
if(j==(LL)1)
c[i][j]=(c[i-1][j]+planet[i].Y);
else
c[i][j]=(c[i-1][j]+(planet[i].Y*c[i-1][j-1]));
}
}
for(int i = 1; i <= n; i++)
f[0][i] = planet[i].Y, t[0][i] = i;
for(int i = 1; (1 << i) <= n; i++) {
for(int j = 1; j + (1 << i) - 1 <= n; j++) {
if(f[i - 1][j] <= f[i - 1][j + (1 << (i-1))]) {
f[i][j] = f[i - 1][j]; t[i][j] = t[i - 1][j];
}
else {
f[i][j] = f[i - 1][j + (1 << (i-1))]; t[i][j] = t[i - 1][j + (1 << (i-1))];
}
}
}
}
pair<LL, LL> RMQ(LL L, LL R) {
LL k = 0;
while(L + (1 << (k+1)) - 1 <= R)
k++;
if(f[k][L] <= f[k][R - (1 << k) + 1]) {
return MP(f[k][L], t[k][L]);
}
return MP(f[k][R - (1 << k) + 1], t[k][R - (1 << k) + 1]);
}
LL getAns(int l,int r,int k)
{
LL ans=c[r][k]-c[l-1][k];
if(k<=0)return 1;
if(k==1)
{
ans=c[r][k]-c[l-1][k];
return ans;
}
for(int i=1;i<=k-1;i++)
{
ans-=c[l-1][i]*getAns(l,r,k-i);
}
return ans;
}
int main()
{
freopen("melancholy.in","r",stdin);
freopen("melancholy.out","w",stdout);
Read(n);Read(q);
for(int i=1;i<=n;i++)Read(planet[i].X);
for(int i=1;i<=n;i++)Read(planet[i].Y);
sort(planet+1,planet+1+n);
pre();
while(q--)
{
Read(l);
Read(r);
Read(k);
l=lower_bound(planet+1,planet+1+n,MP(l,(LL)0))-planet;
r=upper_bound(planet+1,planet+1+n,MP(r,(LL)1e9+8))-planet-1;
if(r<l)
{
printf("0\n");
continue;
}
LL ans=getAns(l,r,k);
pll _min((LL)1e9+8,(LL)1e9+8);
_min=RMQ(l, r);
for(int i=0;k!=1&&i<=k-1;i++)
{
ans-=((getAns(l,_min.Y-1,i)*getAns(_min.Y+1,r,k-i-1))*_min.X);
}
if(k==1)
ans-=_min.X;
cout<<(LL)fac[k]*ans<<endl;
}
int p=1;
}