[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; }
苟利国家生死以, 岂因祸福避趋之。
分类:
数据结构——平衡树
, 实用算法——hash
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 上周热点回顾(1.20-1.26)