首页 > 代码库 > [bzoj2038]莫队算法学习
[bzoj2038]莫队算法学习
解题关键:莫队最重要的是区间之间以$O(1)$的复杂度进行转化,由于电脑原因,后续补上公式推导。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream> 6 #include<cmath> 7 using namespace std; 8 typedef long long ll; 9 ll n,m,ans;10 struct node{11 ll l,r,id;12 }b[50002];13 struct nd{14 ll a,b;15 }as[50002];16 ll a[50002],pos[50002],s[50002];17 18 bool cmp1(const node &a,const node &b){19 return ((pos[a.l]==pos[b.l])&&(a.r<b.r))||(pos[a.l]<pos[b.l]);20 }21 22 void init(){23 ll block=sqrt(n);24 for(int i=1;i<=n;i++) pos[i]=(i-1)/block+1;25 }26 27 void update(ll p,ll add){28 /*ans-=s[a[p]]*s[a[p]];29 s[a[p]]+=add;30 ans+=s[a[p]]*s[a[p]];*/31 ans+=2*add*s[a[p]]+(add==1?0:2);32 s[a[p]]+=add;33 }34 35 void solve(){36 for(int i=1,l=1,r=0;i<=m;i++){37 for(;r<b[i].r;r++) update(r+1,1);38 for(;r>b[i].r;r--) update(r, -1);39 for(;l<b[i].l;l++) update(l, -1);//这里注意搞清楚40 for(;l>b[i].l;l--) update(l-1,1);41 if(b[i].l==b[i].r){42 as[b[i].id].a=0,as[b[i].id].b=1;//题目要求43 continue;44 }45 ll c=ans;46 ll d=(b[i].r-b[i].l+1)*(b[i].r-b[i].l);47 ll k=__gcd(c,d);48 c/=k,d/=k;49 as[b[i].id].a=c,as[b[i].id].b=d;50 }51 }52 int main(){53 cin>>n>>m;54 for(int i=1;i<=n;i++) cin>>a[i];55 for(int i=1;i<=m;i++){56 cin>>b[i].l>>b[i].r;57 b[i].id=i;58 }59 init();60 sort(b+1,b+m+1,cmp1);61 solve();62 for(int i=1;i<=m;i++){63 cout<<as[i].a<<"/"<<as[i].b<<"\n";64 }65 }
[bzoj2038]莫队算法学习
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。