数据流中的算法

 数据流中的算法 - 众数 51Nod - 1786 

数据流统计功能上线后,为51nod提升用户体验做出了很大的贡献。但是新问题随之而来,夹克老爷还想知道在一个窗口内,访问次数最多用户(即窗口内的众数)。如果有多个众数,取用户ID最小的一个。(窗口的意思是一个固定长度的区间!)

(因为数据流是实时的、在线的,所以不允许使用离线算法^_^)

Input

第一行为整数n, k。(1 <= n <= 5 * 10^6,1 <= k <= 1000) 
n代表有多少次操作,k代表窗口大小。 

接下来的n行,每行代表一次操作。每行第一个整数为操作数。 

操作数1:用户访问 
输入格式: <1, id> 
用户ID为0,INTMAX0,INTMAX闭区间内的整数。代表拥有此ID的用户对网站进行了一次访问,窗口进行相应移动。 

操作数2:询问众数 
输入格式:<2> 
输出窗口内的众数,如果有多个,输出ID最小的那个。 

p.s. 对于询问众数的操作,窗口保证不空 
p.s.s. 对于询问众数的操作,窗口可能不满

Output

对于询问众数的操作,每行输出一个整数。

Sample Input

10 5
1 2
1 1
1 2
1 1 
1 2
1 1
2
1 3
1 3
2

Sample Output

1
1

对STL的熟练运用,加上卡常,普通的scanf 和printf 都会很慢,手写一个输入输出流(俗称 输入挂,输出挂)

代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
    int id,cnt;
    bool operator <(const node &a)const{
        return cnt == a.cnt ? id < a.id:cnt > a.cnt;
    }
};
int read()//输入挂
{
    char ch = ' ';
    int ans = 0;
    while(ch <'0'|| ch >'9') ch = getchar();
    while(ch >='0'&& ch <='9'){
        ans = ans*10+ch - '0';
        ch = getchar();
    }
    return ans;
}
void out(int a){//输出挂
    if(a > 9){
        out(a/10);
    }
    putchar(a%10 + '0');
}
int main()
{
    int n,k;
    int a,b;
    queue<int >q;//存输入的id 可以判断存入的id是否大于k;
    map<int ,int >f;//存id的数量;
    set<node> s;//set 会自动排序 输出首位就是题目要求的数据数量最多id最小的(注意结构体重载)
    n = read(),k =read();
    for(int i = 0; i < n; i++){
        a = read();
        if(a == 1){
            b = read();
            f[b]++;//b的数量
            s.insert(node{b,f[b]});//将输入的id存入set
            if(q.size() == k){//如果输入的数据为k个的话那么如果还想输入就得将队列中的首位排出才能存入
                s.erase(s.find((node){q.front(),f[q.front()]}));//找到队列的首位并且删除
                f[q.front()]--;//队列的首位排出那么他的数量减一
                if(f[q.front()]){//如果队列首位的数量大于1,那么就得把剩下的重新存入set因为他只删除了1个队列首位,与队列首位相等的id有很多
                    s.insert((node){q.front(),f[q.front()]});//重新存入set
                }
                if(f[q.front()] == 0){//如果队列首位代表的id数量减一之后为零直接清除掉 没有也行
                    f.erase(q.front());
                }
                q.pop();
            }
            q.push(b);
        }
        else{
            out((*s.begin()).id);//输出set首位 s.begin()代表的是地址;
            putchar('\n');
        }
    }

}

猜你喜欢

转载自blog.csdn.net/qq_41650771/article/details/81380824