秒题

问题描述

签完到后第二天就迎来了考试日。
由于前一天晚上通宵写题,查尔明不得不打起了瞌睡,他终于顶不住了,趴下来补觉。
为了防止 Rank1 被抢走,你需要在查尔明补觉的期间帮他完成第一题。
题目是这样的:
n 个小朋友凑齐钱去拍照。一开始摄影棚中没有任何人,摄影师一共进行了 m 次操作,
每次他会叫编号为 i 的小朋友进来或者出去,然后将摄影棚中所有人按编号从小到大排序后
拍一张照片。
其中有个叫 Mike 的小朋友非常聪明,他对总共 m 张照片进行了仔细观察后发现,有些
照片的本质是相同的!(即拍照的对象相同)也就是说他们多花了许多不必花的钱。你能帮
助他们找出本质不同的照片的数量吗?

输入格式

输入文件 accept.in 第一行包含两个正整数 n,m,表示小朋友的个数和操作的次数。
接下来 m 行,每行包含一个正整数 x,表示让编号为 x 的小朋友进来或出去。

输出格式

输出文件 accept.out 包含一个正整数,即本质不同的照片的数量

题解

  • 讲真,这是一道神奇的题目。随即对于每一个数附一个随机的值(互不相同),然后对于每一步操作,用hash表进行判断(这里用到异或a xor b xor b = a)因此对于每一个产生的结果进行排序和线性判重就好了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <set>
using namespace std;
void fff(){
    freopen("accept.in","r",stdin);
    freopen("accept.out","w",stdout);
}
const int MAXN=100010;
char x[MAXN];
int n,m;
long long h[MAXN],hash[MAXN],ran;
int main(){
    fff();
    int ans=0;
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++) h[i]=ran=ran*233+17;
    for (int i=1;i<=m;i++){
        int x;
        scanf("%d",&x);
        hash[i]=hash[i-1]^h[x];
    }
    int i;
    sort(hash+1,hash+m+1);
    for (hash[0]=hash[1]+1,i=1;i<=m;i++) ans+=hash[i]!=hash[i-1];
    cout<<ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42037034/article/details/80557971