小Z的袜子
Posted rign
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小Z的袜子相关的知识,希望对你有一定的参考价值。
将询问排序分块后每块内部排序
然后每次左端点增减复杂度为√N,每块右端点增减N
每次问询复杂度√N+N
总共有√N次问询
#include <bits/stdc++.h> using namespace std; #define fore(i,a,b) for(int i=(int)(a);i<=(int)(b);i++) #define forb(i,a,b) for(int i=(int)(a);i>=(int)(b);i--) #define fir first #define sec second typedef long long ll; const int N=500010; int c[N],L[N],R[N],num[N]; struct nodeint l,r,id;q[N]; bool cmp(node a,node b)return a.l<b.l || (a.l==b.l && a.r<b.r); bool cmp0(node a,node b)return a.r<b.r; ll ans,anss[N][2],g; int T, n, m; void work(int x,int w)ans-=(ll)num[x]*(num[x]-1);num[x]+=w;ans+=(ll)num[x]*(num[x]-1); ll gcd(ll a,ll b)return b?gcd(b,a%b):a; void gcdab(ll &a,ll &b)g=gcd(a,b);if(!g) b=1; else a/=g,b/=g; int main() cin>>n>>m; fore(i,1,n) scanf("%d",&c[i]); fore(i,1,m) scanf("%d%d",&q[i].l,&q[i].r); q[i].id=i; sort(q+1,q+m+1,cmp); int t=sqrt(m); fore(i,1,t) L[i]=(i-1)*t+1,R[i]=i*t; if(R[t]<n) L[t+1]=R[t]+1,R[++t]=m; fore(i,1,t) memset(num,0,sizeof(num)); sort(q+L[i],q+R[i]+1,cmp0); ans=0; int l=q[L[i]].l,r=q[L[i]].r; fore(j,l,r) work(c[j],1); anss[q[L[i]].id][0]=ans; anss[q[L[i]].id][1]=(ll)(r-l)*(r-l+1); gcdab(anss[q[L[i]].id][0],anss[q[L[i]].id][1]); fore(j,L[i]+1,R[i]) while(r<q[j].r) work(c[++r],1); while(r>q[j].r) work(c[r--],-1); while(l<q[j].l) work(c[l++],-1); while(l>q[j].l) work(c[--l],1); if(q[j].l==q[j].r) anss[q[j].id][0]=0,anss[q[j].id][1]=1; else anss[q[j].id][0]=ans; anss[q[j].id][1]=(ll)(r-l)*(r-l+1); gcdab(anss[q[j].id][0],anss[q[j].id][1]); fore(i,1,m) printf("%lld/%lld\n",anss[i][0],anss[i][1]); return 0;
以上是关于小Z的袜子的主要内容,如果未能解决你的问题,请参考以下文章