直接离线即可.对于每一步都存值即可.(凡是难做的题,都可以考虑离线.)
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5,M=5e5+5;
int ans[M],p[N],v[N],l[M],sum[N],n;
vector<int>r[N];//这个点是第几次查询的时候.
vector<int>kind[N];//记录下种类有多少个了.
int lowbit(int x) { return x&(-x); }
void add(int pos,int val)
{
while(pos<=n)
{
sum[pos]+=val;
pos+=lowbit(pos);
}
}
int query(int pos)
{
int res=0;
while(pos)
{
res+=sum[pos];
pos-=lowbit(pos);
}
return res;
}
int main()
{
int m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
for(int i=1;i<=n;i++) {scanf("%d",&v[i]);add(i,v[i]);}
for(int i=1;i<=m;i++)
{
scanf("%d",&l[i]);
int R;scanf("%d",&R);
r[R].push_back(i);
}
for(int i=1;i<=n;i++)
{
kind[p[i]].push_back(i);
if(kind[p[i]].size()>=k)
{
int pos=kind[p[i]][kind[p[i]].size()-k];
add(pos,-v[pos]);
}
for(int j=0;j<r[i].size();j++)
{
ans[r[i][j]]=query(i)-query(l[r[i][j]]-1);
}
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}

京公网安备 11010502036488号