1. 程式人生 > >bzoj2038: [2009國家集訓隊]小Z的襪子(hose)

bzoj2038: [2009國家集訓隊]小Z的襪子(hose)

space r+ update bsp pre size span 昨天 clu

拍了一早上結果是LL的問題。。。c,%%%rose大佬rp++

昨天珂谷模擬賽,大佬們T2都帶修莫隊65,就我一個暴力40(要是這題+25就機房rank1了。。。)亡羊補牢一下。

化簡一下式子 (a^2+b^2+c^2……)-(r-l+1) / (r-l+1)*(r-.l)

然後就是分塊,排序,之後每次詢問用sqrt(n)就OK

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using
namespace std; typedef long long LL; struct node { int l,r,id; LL fz,fm; }a[51000]; int fk,st[51000]; bool cmp(node n1,node n2) { if(st[n1.l]<st[n2.l]||(st[n1.l]==st[n2.l]&&st[n1.r]<st[n2.r]))return true; return false; } bool cmd(node n1,node n2) { if(n1.id<n2.id)return
true; return false; } int n,m,c[51000];LL ans,s[51000]; void update(int i,int k) { ans-=s[c[i]]*s[c[i]]; s[c[i]]+=k; ans+=s[c[i]]*s[c[i]]; } LL gcd(LL a,LL b) { if(a==0)return b; return gcd(b%a,a); } void solve() { int l=1,r=0;ans=0; memset(s,0,sizeof(s));
for(int i=1;i<=m;i++) { while(r<a[i].r)r++, update(r,1); while(r>a[i].r)update(r,-1), r--; while(l<a[i].l)update(l,-1), l++; while(l>a[i].l)l--, update(l,1); if(a[i].l==a[i].r){a[i].fz=0,a[i].fm=1;continue;} a[i].fz=ans-(a[i].r-a[i].l+1); a[i].fm=(LL)(a[i].r-a[i].l+1)*(LL)(a[i].r-a[i].l); LL k=gcd(a[i].fz,a[i].fm); a[i].fz/=k;a[i].fm/=k; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&c[i]); for(int i=1;i<=m;i++)scanf("%d%d",&a[i].l,&a[i].r), a[i].id=i; fk=int(sqrt(n)); for(int i=1;i<=n;i++)st[i]=(i-1)/fk+1; sort(a+1,a+m+1,cmp); solve(); sort(a+1,a+m+1,cmd); for(int i=1;i<=m;i++)printf("%lld/%lld\n",a[i].fz,a[i].fm); return 0; }

bzoj2038: [2009國家集訓隊]小Z的襪子(hose)