P1494 [國家集訓隊]小Z的襪子(莫隊演算法)
阿新 • • 發佈:2018-12-18
莫隊板子
程式碼
#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #define int long long using namespace std; struct Query{ int l,r,aid; }query[55000]; int ansa[55000],ansb[55000],c[55000],blocknum,midans,sz,belong[55000],n,m,a[55000],lx,rx; bool cmp(Query a,Query b){ return belong[a.l]==belong[b.l]?a.r<b.r:a.l<b.l; } int gcd(int a,int b){ return (b==0)?a:gcd(b,a%b); } void move(int pos,int cs){ midans-=c[a[pos]]*(c[a[pos]]); c[a[pos]]+=cs; midans+=c[a[pos]]*(c[a[pos]]); } signed main(){ scanf("%lld %lld",&n,&m); sz=sqrt(n); blocknum=n/sz; if(n%sz) blocknum++; for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); belong[i]=(i-1)/sz+1; } for(int i=1;i<=m;i++) scanf("%lld %lld",&query[i].l,&query[i].r),query[i].aid=i; sort(query+1,query+m+1,cmp); lx=1,rx=0; for(int i=1;i<=m;i++){ while(lx<query[i].l) move(lx,-1),lx++; while(lx>query[i].l) move(lx-1,1),lx--; while(rx<query[i].r) move(rx+1,1),rx++; while(rx>query[i].r) move(rx,-1),rx--; //move if(query[i].l==query[i].r){ ansa[query[i].aid]=0,ansb[query[i].aid]=1; continue; } ansa[query[i].aid]=midans-(query[i].r-query[i].l+1); ansb[query[i].aid]=(query[i].r-query[i].l+1)*(query[i].r-query[i].l); int Gcd=gcd(ansa[query[i].aid],ansb[query[i].aid]); ansa[query[i].aid]/=Gcd; ansb[query[i].aid]/=Gcd; } for(int i=1;i<=m;i++) printf("%lld/%lld\n",ansa[i],ansb[i]); return 0; }