[分块][哈希] [Romanian IOI 2017 Selection #6] Jolteon && [LOJ #6187] Odd

在loj上看到的题,跟CF77F差不多
但是这不是一个线段,而是一些数字,就不能用同样的方法hash,问了大佬Manchery,恰好他一周前做过……传送门

不过loj上数据更强吧…我Hash打错调了一晚上……

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define fi first
#define se second

using namespace std;

const int N=200010,P=100003;

typedef unsigned long long ull;
typedef pairint> par;

int n,block;
int a[N],lst[N*5];
ull val[N],Hash[N*5];

inline int Hash_(ull x){
  return x%P;
}

struct Hst{
  ull tag;
  Hst(){ tag=cnt=bnt=0; }
  int H[P+5],nxt[550],bin[550],bnt,cnt;
  par key[550];
  void insert(ull x){
    int u=Hash_(x);
    for(int i=H[u];i;i=nxt[i])
      if(key[i].fi==x){ key[i].se++; return ; }
    int cur=bnt?bin[bnt--]:++cnt;
    key[cur]=par(x,1); nxt[cur]=H[u]; H[u]=cur;
  }
  void erase(ull x){
    int u=Hash_(x),v=0,l=0;
    for(int i=H[u];i;l=i,i=nxt[i])
      if(key[i].fi==x) { v=i; break; }
    if(!v) return ; --key[v].se;
    if(key[v].se) return ;
    if(l) nxt[l]=nxt[v]; else H[u]=nxt[v];
    bin[++bnt]=v;
  }
  int count(ull x){
    x^=tag; int u=Hash_(x);
    for(int i=H[u];i;i=nxt[i])
      if(key[i].fi==x) return key[i].se;
      return 0;
  }
}T[550];

void Modify(int l,int r,ull flg){
  int L=l/block,R=r/block;
  if(L==R){
    for(int i=l;i<=r;i++)
      T[L].erase(val[i]),T[L].insert(val[i]^=flg);
    return ;
  }
  for(int i=L+1;ifor(int i=l;i<(L+1)*block;i++)
    T[L].erase(val[i]),T[L].insert(val[i]^=flg);
  for(int i=R*block;i<=r;i++)
    T[R].erase(val[i]),T[R].insert(val[i]^=flg);
}

int Query(int r,ull tar){
  int ret=0,R=r/block;
  for(int i=0;ifor(int i=R*block;i<=r;i++)
    if((val[i]^T[R].tag)==tar) ret++;
  return ret;
}

int main(){
  scanf("%d",&n); block=sqrt(n);
  for(int i=1;i<=n;i++){
    scanf("%d",&a[i]);
    if(!Hash[a[i]]) Hash[a[i]]=1LL*rand()*rand()*rand();
  }
  T[0].insert(0); val[0]=0;
  long long ans=0; ull pre=0;
  for(int i=1;i<=n;i++){
    val[i]=(pre^=Hash[a[i]]);
    T[i/block].insert(val[i]);
    Modify(lst[a[i]],i-1,Hash[a[i]]); lst[a[i]]=i;
    ans+=Query(i-1,pre);
  }
  cout<return 0;
}

你可能感兴趣的:(hash,分块,分块,&,阈值,随机,哈希)