两道模版题 UOj 35 和 bzoj1036
来源:互联网 发布:大数据hadoop分布式 编辑:程序博客网 时间:2024/06/05 03:01
- 后缀数组排序
- 树剖
后缀数组排序:
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e5+10;int n,k,p,q=1;char ch[N];int a[N],v[N],h[N],sa[2][N],rk[2][N];void mul(int *sa,int *rk,int *SA,int *RK){ fo(i,1,n) v[rk[sa[i]]]=i; for(int i=n;i;i--) if(sa[i]>k) SA[v[rk[sa[i]-k]]--]=sa[i]-k; for(int i=n-k+1;i<=n;i++) SA[v[rk[i]]--]=i; fo(i,1,n) RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]]||rk[SA[i]+k]!=rk[SA[i-1]+k]);}void presa(){ for(int i=1;i<=n;i++)v[a[i]]++; for(int i=1;i<=30;i++)v[i]+=v[i-1]; for(int i=1;i<=n;i++) sa[p][v[a[i]]--]=i; for(int i=1;i<=n;i++) rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i-1]]!=a[sa[p][i]]); for(k=1;k<n;k<<=1,swap(p,q)) mul(sa[p],rk[p],sa[q],rk[q]); for(int i=1,k=0;i<=n;i++) { int j=sa[p][rk[p][i]-1]; while(a[i+k]==a[j+k])k++; h[rk[p][i]]=k;if(k>0)k--; }}int main(){ scanf("%s",ch+1); n=strlen(ch+1); fo(i,1,n) a[i]=ch[i]-'a'+1; presa(); fo(i,1,n) printf("%d ",sa[p][i]); puts(""); fo(i,2,n) printf("%d ",h[i]); puts(""); return 0;}
树剖
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=3e4+10,M=6e4+10,inf=(1<<30);int n,q,pos[N],v[N],dep[N],fa[N],size[N],bl[N], head[N],len,sz;struct Edge{int to,next;Edge(int to=0,int next=0):to(to),next(next){}}e[M];void add_edge(int from,int to){ e[++len]=Edge(to,head[from]); head[from]=len;}struct Seg{ int l,r,mx,sum;}t[N<<2];void init(){ scanf("%d",&n); for(int from,to,i=1;i<n;i++) { scanf("%d%d",&from,&to); add_edge(from,to); add_edge(to,from); } fo(i,1,n) scanf("%d",&v[i]);}void dfs1(int x){ size[x]=1; for(int i=head[x];i;i=e[i].next) { int id=e[i].to; if(id==fa[x]) continue; fa[id]=x; dep[id]=dep[x]+1; dfs1(id); size[id]+=size[x]; }}void dfs2(int x,int chain){ int k=0; pos[x]=++sz; bl[x]=chain; for(int i=head[x];i;i=e[i].next) { int id=e[i].to; if(dep[id]>dep[x]&&size[id]>size[k]) k=id; } if(k==0) return ; dfs2(k,chain); for(int i=head[x];i;i=e[i].next) { int id=e[i].to; if(dep[id]>dep[x]&&k!=id) dfs2(id,id); } }void build(int k,int l,int r){ t[k].l=l; t[k].r=r; if(l==r) return ; int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r);}void change(int k,int x,int y){ int l=t[k].l,r=t[k].r,mid=(l+r)>>1; if(l==r) {t[k].mx=t[k].sum=y;return ;} if(x<=mid) change(k<<1,x,y); else change(k<<1|1,x,y); t[k].sum=t[k<<1].sum+t[k<<1|1].sum; t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);}int querysum(int k,int x,int y){ int l=t[k].l,r=t[k].r,mid=(l+r)>>1; if(l==x&&y==r) return t[k].sum; if(y<=mid) return querysum(k<<1,x,y); else if(x>mid) return querysum(k<<1|1,x,y); else {return querysum(k<<1,x,mid)+querysum(k<<1|1,mid+1,y);}}int querymax(int k,int x,int y){ int l=t[k].l,r=t[k].r,mid=(l+r)>>1; if(l==x&&y==r) return t[k].mx; if(y<=mid) return querymax(k<<1,x,y); else if(x>mid) return querymax(k<<1|1,x,y); else {return max(querymax(k<<1,x,mid),querymax(k<<1|1,mid+1,y));}}int solvesum(int x,int y){ int sum=0; while(bl[x]!=bl[y]) { if(dep[bl[x]]<dep[bl[y]]) swap(x,y); sum+=querysum(1,pos[bl[x]],pos[x]); x=fa[bl[x]]; } if(pos[x]>pos[y]) swap(x,y); sum+=querysum(1,pos[x],pos[y]); return sum;}int solvemx(int x,int y){ int mx=-inf; while(bl[x]!=bl[y]) { if(dep[bl[x]]<dep[bl[y]]) swap(x,y); mx=max(querymax(1,pos[bl[x]],pos[x]),mx); x=fa[bl[x]]; } if(pos[x]>pos[y]) swap(x,y); mx=max(mx,querymax(1,pos[x],pos[y])); return mx;}void solve(){ build(1,1,n); fo(i,1,n) change(1,pos[i],v[i]); scanf("%d",&q); char ch[10]; for(int x,y,i=1;i<=q;i++) { scanf("%s%d%d",ch,&x,&y); if(ch[0]=='C') {v[x]=y;change(1,pos[x],y);} else { if(ch[1]=='M') printf("%d\n",solvemx(x,y)); else printf("%d\n",solvesum(x,y)); } }}int main(){ init(); dfs1(1); dfs2(1,1); solve(); return 0;}
阅读全文
0 0
- 两道模版题 UOj 35 和 bzoj1036
- kmp-模版及两道模版题
- Bzoj1036 树链剖分基础题
- bzoj1036树链剖分模板题
- BZOJ1036
- bzoj1036: [ZJOI2008]树的统计Count(树剖模版)
- 两种KMP题+KMP模版整理
- uoj#35: 后缀排序
- 【uoj #35】后缀排序
- 【uoj 35】后缀排序
- [BZOJ1036]树的统计 做题笔记
- UOJ#34 FFT模板题
- 函数模版和类模版
- 函数模版和类模版
- FFT 模版 和 INT128模版
- 别名模版和变量模版
- 【BZOJ1036】树的统计Count-树链剖分模板题
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
- qt make 异常
- 在vue中给列表中的奇数行添加class
- 10 大深度学习架构:计算机视觉优秀从业者必备(附代码实现)
- [排序] 快速排序(Python)
- 机器学习第三课第一部分(矩阵方向变换,正交矩阵)
- 两道模版题 UOj 35 和 bzoj1036
- jemeter打开.jml文件保错
- C++学习——类的常数据成员/常成员函数
- 【JavaMail】(1)JavaMail简介,通过命令行、Java发邮件
- @RequestMapping 用法详解之地址映射(转)
- Java wait() notify()方法使用实例讲解
- 完美的数字
- 一个配置导致的HTTP(TCP)连接超时
- 如何生成密钥,私钥,签名