[POI2008] Poc (原名 Trians) Treap+Hash
Posted TS_Hugh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POI2008] Poc (原名 Trians) Treap+Hash相关的知识,希望对你有一定的参考价值。
这个题和千山鸟飞绝体现出了一种用平衡树解决动态集合问题,主要套路就是蜜汁标记。
这个题我一开始用替罪羊树搞了一下对了28个点,后来我换成了Treap一搞对了14个点,再后来发现被卡了Hash我竟然在自然溢出中用了256....
上代码
#include<cstdio> #include<cstring> #include<map> #include<cstdlib> #define N 1010 #define L 110 #define M 100010 using namespace std; typedef unsigned long long ULL; const ULL base=131; ULL tool[L]; ULL hash[N]; char s[N][L]; int size[N],n,l,m; map<ULL,int>Hash; inline int Max(int x,int y){ return x>y?x:y; } inline void swap(char &a,char &b){char c=a;a=b;b=c;} struct Treap { Treap *ch[2]; int size,Max,i,r; Treap(){ch[1]=ch[0]=NULL;size=Max=i=r=0;} }node[(N+M)<<4],*null,*root[(N+M)<<4]; int sz,tp; inline void Init() { null=node; null->size=null->Max=null->i=null->r=0; null->ch[1]=null->ch[0]=null; for(int i=0;i<((N+M)<<2);i++)root[i]=null; } inline Treap *New(int i) { Treap *p=&node[++sz]; p->ch[1]=p->ch[0]=null; p->Max=0; p->i=i; p->size=1; p->r=rand()+1; return p; } inline void pushup(Treap *p) { if(p==null)return; p->size=p->ch[0]->size+p->ch[1]->size+1; } inline void down(Treap *p,int x) { size[p->i]=Max(size[p->i],x); p->Max=Max(p->Max,x); } inline void pushdown(Treap *p) { if(p->Max==0)return; if(p->ch[0]!=null) down(p->ch[0],p->Max); if(p->ch[1]!=null) down(p->ch[1],p->Max); p->Max=0; } inline void rotate(Treap *&p) { int wh=p->ch[1]->r>p->ch[0]->r; Treap *ch=p->ch[wh]; pushdown(p); pushdown(ch); p->ch[wh]=ch->ch[wh^1]; ch->ch[wh^1]=p; pushup(p); pushup(ch); p=ch; } void insert(Treap *&p,int i) { if(p==null) { p=New(i); return; } pushdown(p); insert(p->ch[p->i<i],i); if(p->r<p->ch[p->i<i]->r)rotate(p); pushup(p); } void del(Treap *&p,int i) { pushdown(p); if(p->i==i) { if(p->ch[0]==null||p->ch[1]==null) { p=p->ch[0]==null?p->ch[1]:p->ch[0]; pushup(p); return; } rotate(p); del(p->ch[p->ch[1]->i==i],i); pushup(p); return; } del(p->ch[p->i<i],i); pushup(p); return; } inline void Insert(int i) { insert(root[Hash[hash[i]]],i); down(root[Hash[hash[i]]],root[Hash[hash[i]]]->size); } inline void Del(int i) { del(root[Hash[hash[i]]],i); } int main() { Init(); scanf("%d%d%d",&n,&l,&m); tool[0]=1; for(int i=1;i<=l;i++) tool[i]=tool[i-1]*base; for(int i=1;i<=n;i++) { scanf("%s",s[i]+1); for(int j=1;j<=l;j++)hash[i]=hash[i]*base+s[i][j]; if(Hash[hash[i]]==0)Hash[hash[i]]=++tp; Insert(i); } for(int i=1;i<=m;i++) { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); Del(a); if(a!=c)Del(c); hash[a]-=s[a][b]*tool[l-b]; hash[c]-=s[c][d]*tool[l-d]; swap(s[a][b],s[c][d]); hash[a]+=s[a][b]*tool[l-b]; hash[c]+=s[c][d]*tool[l-d]; if(Hash[hash[a]]==0)Hash[hash[a]]=++tp; Insert(a); if(a!=c){if(Hash[hash[c]]==0)Hash[hash[c]]=++tp;Insert(c);} } for(int i=1;i<=n;i++)Del(i); for(int i=1;i<=n;i++)printf("%d\n",size[i]); return 0; }
以上是关于[POI2008] Poc (原名 Trians) Treap+Hash的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1125[POI2008]Poc hash+map+SBT