一些常用算法的代码(2)
2016-07-14 16:38
351 查看
主席树
void build(int lst,int now,int l,int r,int v) { if(l==r) { tr[now].sm=tr[lst].sm+1; return; } int mid=(l+r)/2,lts=tr[lst].ls,rts=tr[lst].rs; if (v<=mid) tr[now].rs=rts,tr[now].ls=++nd,build(lts,nd,l,mid,v); else tr[now].ls=lts,tr[now].rs=++nd,build(rts,tr[now].rs,mid+1,r,v); tr[now].sm=tr[tr[now].ls].sm+tr[tr[now].rs].sm; } int find(int lst,int now,int l,int r,int v) { if(l==r) return l; int mid=(l+r)/2; int lts=tr[lst].ls,lns=tr[now].ls,sum=tr[lns].sm-tr[lts].sm; if (sum>=v) find(lts,lns,l,mid,v); else find(tr[lst].rs,tr[now].rs,mid+1,r,v-sum); }
树链剖分
struct note { int mx,ls,rs; }tree[2000005]; struct rd { int x,y; }a[MAXN]; int top[MAXN],size[MAXN],son[MAXN],dfn[MAXN],pt[MAXN],ft[MAXN],deep[MAXN],n,m,a1[MAXN][2],df,num; bool cmp(rd x,rd y) { return x.x<y.x; } void dfs1(int k) { int i,mx=0; if (a1[k][0]!=0) fo(i,a1[k][0],a1[k][1]) { dfs1(a[i].y); size[k]+=size[a[i].y]; if (size[a[i].y]>mx) { son[k]=a[i].y; mx=size[a[i].y]; } } size[k]++; } void dfs2(int k) { int i; dfn[k]=++df; pt[df]=k; if (son[k]!=0) { top[son[k]]=top[k]; dfs2(son[k]); } if (a1[k][0]!=0) fo(i,a1[k][0],a1[k][1]) { if(a[i].y==son[k]) continue; top[a[i].y]=a[i].y; dfs2(a[i].y); } } int find(int now,int l,int r,int x,int y) { if (now==0) return 0; int ls=tree[now].ls,rs=tree[now].rs; if (l==x&&r==y) return tree[now].mx; int mid=(l+r)/2; if (y<=mid) return find(ls,l,mid,x,y); else if(x>mid) return find(rs,mid+1,r,x,y); else return max(find(ls,l,mid,x,mid),find(rs,mid+1,r,mid+1,y)); } void change(int now,int l,int r,int x,int y,int v) { int ls=tree[now].ls,rs=tree[now].rs; if (l==x&&r==y) { tree[now].mx=v; return; } int mid=(l+r)/2; if (ls==0) ls=tree[now].ls=++num,tree[ls].mx=0; if (rs==0) rs=tree[now].rs=++num,tree[rs].mx=0; if (y<=mid) change(ls,l,mid,x,y,v); else if(x>=mid) change(rs,mid+1,r,x,y,v); else change(ls,l,mid,x,mid,v),change(rs,mid+1,r,mid+1,y,v); tree[now].mx=max(tree[ls].mx,tree[rs].mx); } int ask(int x,int y) { int fx=top[x],fy=top[y]; if (fx==fy) { if (deep[x]>deep[y]) swap(x,y); return find(1,1,n,dfn[x],dfn[y]); } else { if (deep[fx]<deep[fy]) swap(fx,fy),swap(x,y); return max(find(1,1,n,dfn[fx],dfn[x]),ask(ft[fx],y)); } }
SA
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<iostream> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) #define fod(i,a,b) for(i=a;i>=b;i--) using namespace std; int n,m; int SA[100001],rank[100001],ct[100001],s2[100001],r1[100001],height[100001]; char st[100001]; void findh() { height[1]=0; int i=0,j; fo(i,1,n) { if (rank[i]==1) continue; j=max(height[rank[i-1]]-1,0); while (st[i+j]==st[SA[rank[i]-1]+j]) j++; height[rank[i]]=j; } } void make() { memset(ct,0,sizeof(ct)); int i,j,k,mx; fo(i,1,n) ct[rank[i]=st[i]]++; fo(i,1,m) ct[i]+=ct[i-1]; fod(i,n,1) SA[ct[rank[i]]--]=i; mx=m; for(j=1,k=0;k<n;j*=2,mx=k) { int p=0; fo(i,n-j+1,n) s2[++p]=i; fo(i,1,n) if(SA[i]>j) s2[++p]=SA[i]-j; memset(ct,0,sizeof(ct)); fo(i,1,n) ct[rank[s2[i]]]++; fo(i,1,mx) ct[i]+=ct[i-1]; fod(i,n,1) SA[ct[rank[s2[i]]]--]=s2[i]; r1[SA[1]]=k=1; fo(i,2,n) r1[SA[i]]=(rank[SA[i-1]]==rank[SA[i]]&&rank[SA[i-1]+j]==rank[SA[i]+j])?k:++k; fo(i,1,n) rank[i]=r1[i]; } } int main() { freopen("SA.in","r",stdin); scanf("%s",st+1); n=strlen(st+1); int i; fo(i,1,n) { int cm=st[i]; m=max(m,cm); } make(); fo(i,1,n) printf("%d ",SA[i]); cout<<endl; findh(); fo(i,2,n) printf("%d ",height[i]); }
莫比乌斯反演
#include<cstdio> #include<cstdlib> #include<algorithm> #include<iostream> #include<cstring> #include<cmath> #define fo(i,a,b) for(i=a;i<=b;i++) #define fod(i,a,b) for(i=a;i>=b;i--) using namespace std; long long mu[50005]; int a,b,c,d,k; int prime[50005],n; bool bz[50005]; void getprime(int lim) { int i,j,num=0; fo(i,2,lim) { if (!bz[i]) { prime[++num]=i; mu[i]=-1; } for(j=1;i*prime[j]<=lim&&j<=num;j++) { if (i*prime[j]>50000) break; bz[i*prime[j]]=1; if (prime[j]==i) break; if (!(i%prime[j])) { mu[i*prime[j]]=0; break; } mu[i*prime[j]]=-mu[i]; } } } int find(int k,int mx,int my) { int i=1,j; long long ans=0; while(i<=trunc(min(mx,my)/k)) { j=min(mx/(mx/i),my/(my/i)); ans+=trunc(my/(i*k))*trunc(mx/(i*k))*(mu[j]-mu[i-1]); i=j+1; } return (int)ans; } int main() { freopen("inversion.in","r",stdin); getprime(50000); scanf("%d",&n); mu[1]=1; int i; fo(i,2,50000) mu[i]+=mu[i-1]; while(n-->0) { scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); printf("%d\n",(int)(find(k,b,d)-find(k,a-1,d)-find(k,b,c-1)+find(k,a-1,c-1))); } }
相关文章推荐
- Java 自动装箱和拆箱
- Activiti基础教程--06流程变量
- hightcharts java的实现实例显示类型bar柱形
- Jaxb2 实现JavaBean与xml互转
- Java反射机制
- Java常见异常总结
- 构造、拷贝构造、赋值
- C# ?? 运算符
- Java中为什么要使用抽象类
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- java 显示当前时间 (集锦)
- 使用jersey构建Restful web service
- springMVC中controller之前执行的方法
- [python]去掉 unicode 字符串前面的 u(转)
- AOP面向方面(切面)编程
- 习题4 变量和命名
- C# FileStream Write追加写入文本
- Learning Python 001 第一个程序
- Learning Python 001 第一个程序
- C# FileStream 按大小分段读取文本内容