洛谷P1494 [国家集训队]小Z的袜子
Code:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cmath> # define REP(i,a,n) for(int i=a;i<=n;++i) # define CLR(d,a)memset(d,a,sizeof(d)); using namespace std; void SetIO(string a){ string in=a+".in"; freopen(in.c_str(),"r",stdin); } const int maxn=60000+5; int n,m,col[maxn]; struct Asks{ int l,r; Asks(int l=0,int r=0):l(l),r(r){} }asks[maxn]; void Read(){ scanf("%d%d",&n,&m); REP(i,1,n) scanf("%d",&col[i]); REP(i,1,m){ int a,b; scanf("%d%d",&a,&b); asks[i]=Asks(a,b); } } int block; int belong[maxn], ranking[maxn]; int get_belong(int i){ return (i-1)/block+1; } bool cmp(int i,int j){ if(belong[asks[i].l]==belong[asks[j].l]) return asks[i].r<asks[j].r; else return belong[asks[i].l]<belong[asks[j].l]; } void Build(){ block=sqrt(n); REP(i,1,n) belong[i]=get_belong(i); REP(i,1,m) ranking[i]=i; sort(ranking+1,ranking+1+m, cmp); } long long square[maxn], ans[maxn]; long long cnt[maxn]; long long sum_square=0; void update(int t, int delta){ sum_square-=square[t]; cnt[t]+=delta; square[t]=cnt[t]*cnt[t]; sum_square+=square[t]; } void Work(){ int l=asks[ranking[1]].l, r=asks[ranking[1]].r; REP(i,l,r) ++cnt[col[i]]; REP(i,1,n){ square[i]=cnt[i]*cnt[i]; sum_square+=square[i]; } REP(i,1,m){ ans[ranking[i]]=sum_square; if(i==m)break; int l2=asks[ranking[i+1]].l; int r2=asks[ranking[i+1]].r; if(r<r2) REP(i,r+1,r2) update(col[i],1); else for(int i=r;i>r2;--i) update(col[i],-1); if(l>l2) for(int i=l-1;i>=l2;--i)update(col[i],1); else REP(i,l,l2-1)update(col[i],-1); l = l2; r = r2; } } long long gcd(long long a,long long b){ return b==0?a:gcd(b,a%b); } long long up[maxn], down[maxn]; void Print(){ REP(i,1,m){ int l=asks[i].l; int r=asks[i].r; if(l==r){ up[i]=0; down[i]=1; } else{ int length=r-l+1; up[i]=ans[i]-length; down[i]=(long long)length*(length-1); if(up[i]==0){ up[i]=0; down[i]=1; continue; } long long k=gcd(up[i],down[i]); up[i]/=k; down[i]/=k; } } REP(i,1,m) printf("%lld/%lld\n",up[i],down[i]); } int main(){ SetIO("input"); Read(); Build(); Work(); Print(); return 0; }