bzoj2038 [2009国家集训队]小Z的袜子(hose) (分块)

来源:互联网 发布:四轴飞控算法 编辑:程序博客网 时间:2024/06/11 02:28

题意:中文题。。。

用分块写的,每次增加一个数x,能形成的种数,ans就增加2*cnt[x],然后再cnt[x]++,每减少一个数,cnt[x]--,ans减少2*cnt[x]。。。就是这样搞了。。

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const int MAXN=50010;int vec[MAXN],idx;int a[MAXN];int cnt[MAXN];typedef long long ll;ll ans1[MAXN],len[MAXN];struct Query{int l,r,pos,id;bool operator < (const Query &rhs) const{if(pos==rhs.pos)return r<rhs.r;return pos<rhs.pos;}}q[MAXN];int HASH(int x){int l=1,r=idx;while(l<=r){int mid=(l+r)>>1;if(vec[mid]==x)return mid;if(x>vec[mid])l=mid+1;elser=mid-1;}return l;}ll ans;void erase(int x){cnt[a[x]]--;ans-=2*cnt[a[x]];}void insert(int x){ans+=2*cnt[a[x]];cnt[a[x]]++;}ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}int main(){int n,m,i;while(scanf("%d%d",&n,&m)==2){idx=0;for(i=1;i<=n;i++){scanf("%d",&a[i]);vec[++idx]=a[i];}vec[1]=a[1];sort(vec+1,vec+idx+1);int k=1;for(i=2;i<=idx;i++){if(vec[k]!=vec[i])vec[++k]=vec[i];}for(i=1;i<=n;i++){a[i]=HASH(a[i]);}for(i=0;i<m;i++){scanf("%d%d",&q[i].l,&q[i].r);q[i].pos=q[i].l/sqrt(n);q[i].id=i;}sort(q,q+m);int p1=1,q1=1;cnt[a[p1]]++;ans=0;for(i=0;i<m;i++){int l=q[i].l,r=q[i].r;while(q1<r)insert(++q1);while(q1>r)erase(q1--);while(p1<l)erase(p1++);while(p1>l)insert(--p1);ans1[q[i].id]=ans;len[q[i].id]=(ll)(q[i].r-q[i].l+1)*(ll)(q[i].r-q[i].l);}for(i=0;i<m;i++){ll temp1=ans1[i];ll temp2=len[i];if(temp1==0){printf("0/1\n");continue;}ll d=gcd(temp1,temp2);temp1/=d,temp2/=d;printf("%lld/%lld\n",temp1,temp2);}}return 0;}


0 0