小P的太空旅行

小P的太空旅行

时间限制: 1 Sec  内存限制: 128 MB
提交: 41  解决: 17
[提交] [状态] [讨论版] [命题人:admin]

题目描述

今年是8102年,小P去M870星球旅行了。M870星球景色优美,食物非常美味,所以全宇宙的人都爱去M870星球旅行。

这些来旅行的游客可以看作一排,来自不同星球的旅客的识别码是不同的,识别码是由1到k的,不同识别码表示不同星球的旅客。

小P想要知道,在一个区间里有多少种出现次数恰好为T次的旅客。

输入

第一行四个整数n,m,k,T(1<=n,m,k,T<=5*10^5)。

第二行n个整数,第i个整数为a[i],表示对应旅客的种族(1<=a[i]<=k)。

接下来m行,每行两个整数l[i]和r[i],表示询问的区间(1<=l[i]<=r[i]<=n)。

输出

输出m行,每行一个整数,第i行表示第i次询问的答案。

样例输入

10 5 5 1
1 5 3 4 2 4 1 2 3 5 
1 10
3 6 
2 8
5 7
6 10

样例输出

0
2
3
3
5

提示

对于30%的数据 n,m,k<=2000,T<=n.
对于另外40%的数据 T=1,1<=n,m,k<=5*10^5.
对于所有数据,1<=n,m,k,T<=5*10^5,1<=a[i]<=k,1<=l[i]<=r[i]<=n.
注意:本题输入量较大,请使用较为快速的读入方式。

Solution:注意一下输入输出的优化就好了。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include<bits/stdc++.h>
#define REP(i, a, b) for(int i = (a); i <= (b); ++ i)
#define REP(j, a, b) for(int j = (a); j <= (b); ++ j)
#define PER(i, a, b) for(int i = (a); i >= (b); -- i)
using namespace std;
const int maxn=5e5+10;
template <class T>
inline void rd(T &ret){
    char c;
    ret = 0;
    while ((c = getchar()) < '0' || c > '9');
    while (c >= '0' && c <= '9'){
        ret = ret * 10 + (c - '0'), c = getchar();
    }
}
template <class T>
inline void print_d(T x){
    if(x > 9)print_d(x / 10);
    putchar(x % 10 + '0');
}
struct node{
     int l,r,id,pos;
     bool operator<(const node& x){
          if(pos==x.pos)return r<x.r;
          else return pos<x.pos;
     }
}q[maxn];
int n,m,k,t,p[maxn],ans[maxn],vis[maxn];
int squre;
int main(){
    ios::sync_with_stdio(false);
    rd(n),rd(m),rd(k),rd(t);
    squre=sqrt(n);
    REP(i,1,n)rd(p[i]);
    REP(i,1,m){
        rd(q[i].l),rd(q[i].r);
        q[i].id=i,q[i].pos=q[i].l/squre;
    }
    sort(q+1,q+1+m);
    int l=1,r=0,cur=0;
    REP(i,1,m){
          int cl=q[i].l,cr=q[i].r;
          while(cl<l){
               vis[p[--l]]++;
               if(vis[p[l]]==t)cur++;
               else if(vis[p[l]]!=t&&vis[p[l]]-1==t)cur--;
          }
          while(cl>l){
               vis[p[l]]--;
               if(vis[p[l]]==t)cur++;
               else if(vis[p[l]]!=t&&vis[p[l]]+1==t)cur--;
               l++;
          }
          while(cr<r){
               vis[p[r]]--;
               if(vis[p[r]]==t)cur++;
               else if(vis[p[r]]!=t&&vis[p[r]]+1==t)cur--;
               r--;
          }
          while(cr>r){
               vis[p[++r]]++;
               if(vis[p[r]]==t)cur++;
               else if(vis[p[r]]!=t&&vis[p[r]]-1==t)cur--;
          }
          ans[q[i].id]=cur;
     }
     REP(i,1,m){
         print_d(ans[i]);
         puts("");
     }
     return 0;
}

猜你喜欢

转载自www.cnblogs.com/czy-power/p/10398500.html