bzoj2038 [2009国家集训队]小Z的袜子(hose)
由于今天在模拟赛上遇到一道树上莫队,我爆零了,所以我特地来学习了莫队算法
我觉得莫队算法就是那四个循环,update实现O(1)转移来保证复杂度
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n,m,c[50050],wei[50050]; 34 struct question 35 { 36 int l,r,id; 37 LL a,b; 38 void in(int i){inin(l),inin(r),id=i;} 39 bool op < (const question &rhs)const {return wei[l]==wei[rhs.l]?r<rhs.r:l<rhs.l;} 40 }q[50050]; 41 bool com(const question &a,const question &b) 42 { 43 return a.id<b.id; 44 } 45 LL gcd(LL a,LL b) 46 { 47 LL c; 48 while(a%b)c=a%b,a=b,b=c; 49 return b; 50 } 51 LL ans,s[50050]; 52 void update(int we,int add) 53 { 54 ans-=s[c[we]]*s[c[we]]; 55 s[c[we]]+=add; 56 ans+=s[c[we]]*s[c[we]]; 57 } 58 void solve() 59 { 60 int l=1,r=0; 61 re(i,1,m) 62 { 63 while(r<q[i].r)update(++r,1); 64 while(r>q[i].r)update(r--,-1); 65 while(l<q[i].l)update(l++,-1); 66 while(l>q[i].l)update(--l,1); 67 if(q[i].l==q[i].r){q[i].a=0,q[i].b=1;continue;} 68 q[i].a=ans-(q[i].r-q[i].l+1); 69 q[i].b=(LL)(q[i].r-q[i].l+1)*(q[i].r-q[i].l); 70 LL k=gcd(q[i].a,q[i].b); 71 q[i].a/=k,q[i].b/=k; 72 } 73 } 74 int CSC() 75 { 76 inin(n),inin(m); 77 re(i,1,n)inin(c[i]); 78 int block=sqrt(n); 79 re(i,1,n)wei[i]=(i-1)/block+1; 80 re(i,1,m)q[i].in(i); 81 sort(q+1,q+m+1); 82 solve(); 83 sort(q+1,q+m+1,com); 84 re(i,1,m)printf("%lld/%lld\n",q[i].a,q[i].b); 85 return 0; 86 }