Codechef Aug2017 #Walks on the binary tree -- 主席树+Hash
来源:互联网 发布:五金淘宝店铺表示 编辑:程序博客网 时间:2024/05/29 05:07
传送门
每次答案增加的值就是
而与
于是可以用
每个点用主席树+hash维护。
代码
#include<set>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define N 100010#define P1 127#define P2 233#define M1 1000000007#define M2 1000000009struct Hash{ int s1,s2; Hash(int s1=0,int s2=0):s1(s1),s2(s2){} bool operator == (Hash a)const{ return s1==a.s1&&s2==a.s2; } Hash operator + (Hash a)const{ return Hash((s1+a.s1)%M1,(s2+a.s2)%M2); } Hash operator * (int p)const{ return Hash(s1*p,s2*p); }};typedef Hash ull;struct Node{ int l,r,p,s; ull w;}c[N*75];int h1[N],h2[N],s1[N],s2[N];int i,j,k,n,m,p,T,Q,Num,x,Cur;long long Ans;char ss[2];inline void Up(int x){ c[x].s=c[c[x].l].s+c[c[x].r].s; c[x].w=c[c[x].l].w+c[c[x].r].w;}inline void Ch(int& x,int y,int p,int l,int r){ x=++Num; c[x].l=c[y].l;c[x].r=c[y].r; c[x].p=p; c[x].w=Hash((s1[r]-s1[l-1]+M1)%M1,(s2[r]-s2[l-1]+M2)%M2)*p; c[x].s=(r-l+1)*p;}inline void Down(int x,int l,int r){ if(c[x].p!=-1){ int Mid=l+r>>1; Ch(c[x].l,c[x].l,c[x].p,l,Mid);Ch(c[x].r,c[x].r,c[x].p,Mid+1,r); c[x].p=-1; }}inline bool Query(int x,int l,int r,int y){ if(!x)return 0; Down(x,l,r); if(l==r)return c[x].s; int Mid=l+r>>1; if(y<=Mid)return Query(c[x].l,l,Mid,y); return Query(c[x].r,Mid+1,r,y);}inline void Insert(int& x,int y,int l,int r,int L,int R,int p){ if(l>R||r<L)return; Down(x,l,r); if(l>=L&&r<=R){ Ch(x,y,p,l,r); return; } x=++Num;c[x].l=c[y].l;c[x].r=c[y].r;c[x].p=-1; int Mid=l+r>>1; Insert(c[x].l,c[y].l,l,Mid,L,R,p); Insert(c[x].r,c[y].r,Mid+1,r,L,R,p); Up(x);}inline int Find(int x,int l,int r,int y){ if(l==r)return c[x].s?-1:l; Down(x,l,r); int Mid=l+r>>1; if(l>=y){ if(c[c[x].l].s<Mid-l+1)return Find(c[x].l,l,Mid,y); return Find(c[x].r,Mid+1,r,y); } if(y>Mid)return Find(c[x].r,Mid+1,r,y); int t=Find(c[x].l,l,Mid,y); return t==-1?Find(c[x].r,Mid+1,r,y):t; }inline void Update(int& x,int z){ bool t=Query(x,1,n,z); if(!t)Insert(x,x,1,n,z,z,1);else{ int p=Find(x,1,n,z); if(p==-1)p=n+1; Insert(x,x,1,n,z,p-1,0); if(p<=n)Insert(x,x,1,n,p,p,1); }}inline bool Check(int x,int y,int l,int r){ if(!c[y].s)return 0; if(!c[x].s)return 1; Down(x,l,r);Down(y,l,r); if(l==r)return 0; int Mid=l+r>>1; if(c[c[x].r].w==c[c[y].r].w)return Check(c[x].l,c[y].l,l,Mid); return Check(c[x].r,c[y].r,Mid+1,r);}inline int Get(int x,int y,int l,int r){ if(x)Down(x,l,r); if(y)Down(y,l,r); if(l==r)return l; int Mid=l+r>>1; if(c[c[x].r].w==c[c[y].r].w)return Get(c[x].l,c[y].l,l,Mid); return Get(c[x].r,c[y].r,Mid+1,r);}struct D{ int x; D(int x=0):x(x){} bool operator < (D y)const{ return Check(x,y.x,1,n); }}t;set<D>S;set<D>::iterator It;int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&Q); Num=Cur=0;Ans=1;S.clear();c[0].p=-1; h1[0]=h2[0]=1; for(i=1;i<=n;i++)h1[i]=1ll*h1[i-1]*P1%M1,h2[i]=1ll*h2[i-1]*P2%M2,s1[i]=(h1[i]+s1[i-1])%M1,s2[i]=(h2[i]+s2[i-1])%M2; while(Q--){ scanf("%s",ss); if(ss[0]=='?')printf("%lld\n",Ans);else{ scanf("%d",&x);x++; Update(Cur,x); t=D(Cur); if(S.find(t)!=S.end())continue; It=S.insert(t).first; m=n; It++; if(It!=S.end())m=Get(Cur,It->x,1,n); It--; if(It!=S.begin()){ It--; m=min(m,Get(Cur,It->x,1,n)); } Ans+=m; } } } return 0;}
阅读全文
0 0
- Codechef Aug2017 #Walks on the binary tree -- 主席树+Hash
- [主席树维护HASH && SET维护DFS序] Codechef. Walks on the binary tree
- [主席树 Hash] Codechef JUNE17 #CLONEME Cloning
- [主席树维护HASH] Codechef. Cloning
- BZOJ 3221 [Codechef FEB13] Obserbing the tree树上询问 树链剖分 主席树维护区间加等差数列
- BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问 树链剖分 主席树
- SPOJ 10628 Count on The tree .. .. 主席树
- Random Walks on the Click Graph
- 【主席树】 SPOJ Count on a tree
- spoj Count on a tree【主席树】
- bzoj2588 count on a tree 主席树
- 【bzoj2588】Count on a tree 主席树
- [bzoj2588][主席树]Count on a tree
- 【主席树】Codechef Prefix XOR
- [主席树] Codechef: Prefix XOR
- [CODECHEF]Prime Distance On Tree
- CodeChef PRIMEDSTPrime Distance On Tree
- 【codechef】Fibonacci Numbers on Tree
- 解决MySql 数据库 提示:1045 access denied for user 'root'@'localhost' using password yes
- C++公有保护私有继承方式权限
- EasyNVR H5无插件直播方案前端构建之:实时直播的四分屏的前端展示
- laravel定时任务怎么写
- 8.27 题解
- Codechef Aug2017 #Walks on the binary tree -- 主席树+Hash
- js转换Date日期格式
- sys.stdout.flush()
- iOS开发 CGContextRef画图使用
- 第一个Java程序,输出“HelloWorld”。
- Iterator之remove情况分析之一报错原因
- 视频内容谁来保护?阿里云视频加密技术大揭秘,打造云上视频安全体系
- 判断是否是相同二叉树&&判断是否是对称树
- What is JSON Wire Protocol?