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

来源:互联网 发布:百视通网络机顶盒破解 编辑:程序博客网 时间:2024/05/20 17:24

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

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

#include <cstdio>#include <iostream>#include <algorithm>#include <cmath>#include <string>#include <cstring>#include <map>#define fi first#define se secondusing namespace std;const int N=200010,P=100003;typedef unsigned long long ull;typedef pair<ull,int> 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;i<R;i++) T[i].tag^=flg;  for(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;i<R;i++)    ret+=T[i].count(tar);  for(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<<ans<<endl;  return 0;}
原创粉丝点击