【莫队算法】小z的袜子
来源:互联网 发布:linux查看cpu命令 编辑:程序博客网 时间:2024/05/19 23:02
题目:给定n个数a1, a2…… an与m个询问(L,R)。对于每个询问,从aL, aL+1…… aR这R-L+1个数中随机取出两个数,求这两个数相同的概率。
假设我们当前处理了询问(l1,r1),那么下个询问(l2,r2)需要操作的次数是|l1-l2|+|r1-r2|,其实就是曼哈顿距离,那么只需求出哈密尔顿路径即可确定操作序列,但是tsp不好求,则我们求出曼哈顿距离最小生成树,可知大小不超过tsp的两倍,莫队证出按此顺序操作复杂度是o(nsqrt(m))
曼哈顿距离最小生成树据说可以分成两块做,但是我实在觉得偏序关系处理起来有问题,所以还是扫了4遍,因为不想离散,所以用了一个奇怪的顺序排的
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>const int oo=1073741819;int tail[50005],next[1000000],sora[1000000],a[50005],c[50005],l[50005],r[50005],x[50005],y[50005],b[5][131072];int ll[500000],rr[500000],w[500000],f[50005],u[500000];int tim,n,m,m1,ss,tot,p,q,low,lim;long long ans,ans1[50005],ans2[50005],tmp;bool v[50005];void origin() { for (m1=1;m1<=n+2;m1<<=1) ;m1++; for (int i=1;i<=m+1;i++) tail[i]=i;ss=m+1,tot=0;}inline int cmp1(const void *i,const void *j){ p=*(int *)i,q=*(int *)j; if (y[p]-x[p]!=y[q]-x[q]) return (y[q]-x[q])-(y[p]-x[p]); return x[p]-x[q];}inline int cmp2(const void *i,const void *j){ p=*(int *)i,q=*(int *)j; if (y[p]+x[p]!=y[q]+x[q]) return (y[q]+x[q])-(y[p]+x[p]); return x[p]-x[q];}inline int min(int e,int a,int b){ if (e<=2) return (x[a]+y[a]<=x[b]+y[b]) ? a : b; return (y[a]-x[a]<=y[b]-x[b]) ? a : b;}inline void change(int e,int x,int u){ for (x+=m1;x;x>>=1) {b[e][x]=min(e,b[e][x],u);if (b[e][x]!=u) return ; }}inline int ask(int e,int l,int r){ int sum=0; if (l>r) return 0; l+=m1-1,r+=m1+1; for (;!(1==(l^r));l>>=1,r>>=1) {if (0==(l&1)) sum=min(e,sum,b[e][l+1]);if (1==(r&1)) sum=min(e,sum,b[e][r-1]); } return sum;}void link(int p,int q){ if (!p || !q) return ; tot++; ll[tot]=p,rr[tot]=q,w[tot]=abs(x[p]-x[q])+abs(y[p]-y[q]);}void mysoul(){ int i,xx; x[0]=0,y[0]=oo; qsort(u+1,m+1,sizeof(u[1]),cmp1);tim=1; for (i=1;i<=m+1;i++) {xx=ask(tim,x[u[i]],n);link(u[i],xx);change(tim,x[u[i]],u[i]); } tim=2; for (i=m+1;i>=1;i--) {xx=ask(tim,y[u[i]]+1,n);link(u[i],xx);change(tim,y[u[i]],u[i]); } qsort(u+1,m+1,sizeof(u[1]),cmp2);tim=3; for (i=1;i<=m+1;i++) {xx=ask(tim,0,x[u[i]]-1);link(u[i],xx);change(tim,x[u[i]],u[i]); } tim=4; for (i=m+1;i>=1;i--) {xx=ask(tim,y[u[i]],n);link(u[i],xx);change(tim,y[u[i]],u[i]); }}int find(int x) {if (f[x]!=x) f[x]=find(f[x]);return f[x];}int cmp3(const void *i,const void *j) {return w[*(int *)i]-w[*(int *)j];}long long gcd(long long a,long long b){ long long t; for (;a%b;) {t=a%b;a=b;b=t; } return b;}inline void del(int l,int r) {for (int i=l;i<=r;i++) c[a[i]]--,ans-=c[a[i]];}inline void add(int l,int r) {for (int i=l;i<=r;i++) ans+=c[a[i]],c[a[i]]++;}void dfs(int x){ int i,ne; if (r[x]>lim) add(lim+1,r[x]); if (l[x]<low) add(l[x],low-1); if (r[x]<lim) del(r[x]+1,lim); if (l[x]>low) del(low,l[x]-1); low=l[x],lim=r[x]; ans1[x]=ans,v[x]=1; for (i=x;next[i]!=0;) {i=next[i],ne=sora[i];if (!v[ne]) dfs(ne); }}void link2(int x,int y){ ss++,next[tail[x]]=ss,tail[x]=ss,sora[ss]=y; ss++,next[tail[y]]=ss,tail[y]=ss,sora[ss]=x;}void init(){ int i,ls,rs; scanf("%d%d\n",&n,&m); origin(); for (i=1;i<=n;i++) scanf("%d",&a[i]); for (i=1;i<=m;i++) {scanf("%d%d\n",&l[i],&r[i]);x[i]=l[i],y[i]=r[i]+1;ans2[i]=((long long)r[i]-l[i]+1)*(r[i]-l[i])/2;u[i]=i; } l[m+1]=r[m+1]=x[m+1]=y[m+1]=0,u[m+1]=m+1; mysoul(); for (i=1;i<=tot;i++) u[i]=i; qsort(u+1,tot,sizeof(u[1]),cmp3); for (i=1;i<=m+1;i++) f[i]=i; for (i=1,tmp=m;i<=tot && tmp;i++) {ls=find(ll[u[i]]),rs=find(rr[u[i]]);if (ls!=rs) f[ls]=rs,tmp--,link2(ll[u[i]],rr[u[i]]); } low=lim=1,ans=0,c[a[1]]=1; dfs(m+1); for (i=1;i<=m;i++) {tmp=gcd(ans1[i],ans2[i]);printf("%I64d/%I64d\n",ans1[i]/tmp,ans2[i]/tmp); }}int main(){ freopen("hose.in","r",stdin); freopen("hose.out","w",stdout); init(); return 0;}
- 【莫队算法】小z的袜子
- 小Z的袜子(莫队算法)
- 小Z的袜子【莫队算法】
- 小Z的袜子【莫队算法】
- 莫队算法 小Z的袜子
- 【BZOJ2038】小Z的袜子,第一次的莫队算法
- 【BZOJ】【P2038】【小Z的袜子】【题解】【莫队算法】
- 小Z的袜子 (莫队算法)
- [2009国家集训队]小Z的袜子--莫队算法
- 清橙A1206 小Z的袜子(莫队算法)
- 线性莫队算法 BZOJ 2038 小Z的袜子
- [BZOJ2038]2009集训队 小Z的袜子|莫队算法
- HYSBZ 2038 小z的袜子(hose) 莫队算法
- 小Z的袜子(莫队算法)
- 小Z的袜子(hose) - bzoj 2038 莫队算法
- HYSBZ 2038 小Z的袜子 莫队算法
- 大视野2038 小z的袜子 莫队算法
- syhbz 2038 小z的袜子(莫队算法)
- Android NFC 开发教程(2): ApiDemos->NFC->ForegoundDispatch
- Android测试教程(7):测试Content Provider
- Android OpenGL ES 开发教程(7):创建实例应用OpenGLDemos程序框架
- 【恶心容斥】梭哈游戏
- zend stdio 8.0 快捷键总结
- 【莫队算法】小z的袜子
- linux 重定向
- 终于开通博客了
- dorado要点总结
- 循序渐进学好编程,不要太急!!!
- 使用SqlDependency时提示当前数据库未启用Service broker
- 关于骨骼动画及微软示例Skinned Mesh的解析
- 汉字转unicode的方法
- Little Android Project Share >.<