直接离线即可.对于每一步都存值即可.(凡是难做的题,都可以考虑离线.)
代码如下:

#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;
}