网上大片的莫队算法题解,先orz一下莫队
什么不会莫队?没事我来篇低端的
分块大法好啊,我们知道对于区间[l,r]答案是S/P P是一下子可以算出来的,S=∑(pj-1)*pj/2 pj表示区间内颜色为j的数目
先记录ans[i,j]表示第i块到第j块之间的S
然后再记录颜色g[i,j]表示到第i块颜色为j的数目
然后暴力统计不在整块内颜色对答案的贡献即可
20分钟就1A了,非常好写
虽然理论复杂度和莫队差不多O(nsqrt(n))
但是实际上似乎被莫队完败了,但是没关系,毕竟我们这是在线算法啊
1 var f:array[0..230,0..230] of longint; 2 g:array[0..50010,0..230] of longint; 3 be,c,s:array[0..50010] of longint; 4 size,p,t,i,n,m,x,y:longint; 5 6 function gcd(a,b:longint):longint; 7 begin 8 if b=0 then exit(a) 9 else exit(gcd(b,a mod b)); 10 end; 11 12 procedure prework; 13 var i,j:longint; 14 begin 15 for i:=1 to n do 16 inc(g[c[i],be[i]]); 17 for i:=1 to p do 18 for j:=2 to t do 19 inc(g[i,j],g[i,j-1]); 20 for i:=1 to t do 21 begin 22 for j:=(i-1)*size+1 to n do 23 begin 24 if j mod size=1 then f[i,be[j]]:=f[i,be[j]-1]; 25 inc(f[i,be[j]],s[c[j]]); 26 inc(s[c[j]]); 27 end; 28 fillchar(s,sizeof(s),0); 29 end; 30 end; 31 32 procedure clear(l,r:longint); 33 var i:longint; 34 begin 35 for i:=l to r do 36 s[c[i]]:=0; 37 end; 38 39 procedure ask(x,y:longint); 40 var i,a,b,d:longint; 41 begin 42 b:=int64(y-x+1)*int64(y-x) div 2; 43 a:=0; 44 if be[x]=be[y] then 45 begin 46 for i:=x to y do 47 begin 48 a:=a+s[c[i]]; 49 inc(s[c[i]]); 50 end; 51 clear(x,y); 52 end 53 else begin 54 a:=f[be[x]+1,be[y]-1]; 55 for i:=x to be[x]*size do 56 begin 57 if s[c[i]]=0 then s[c[i]]:=g[c[i],be[y]-1]-g[c[i],be[x]]; 58 a:=a+s[c[i]]; 59 inc(s[c[i]]); 60 end; 61 for i:=(be[y]-1)*size+1 to y do 62 begin 63 if s[c[i]]=0 then s[c[i]]:=g[c[i],be[y]-1]-g[c[i],be[x]]; 64 a:=a+s[c[i]]; 65 inc(s[c[i]]); 66 end; 67 clear(x,be[x]*size); 68 clear((be[y]-1)*size+1,y); 69 end; 70 d:=gcd(a,b); 71 writeln(a div d,'/',b div d); 72 end; 73 74 begin 75 readln(n,m); 76 size:=trunc(sqrt(n)); 77 for i:=1 to n do 78 begin 79 read(c[i]); 80 if c[i]>p then p:=c[i]; 81 be[i]:=(i-1) div size+1; 82 end; 83 t:=i div size; 84 if i mod size<>0 then inc(t); 85 prework; 86 for i:=1 to m do 87 begin 88 readln(x,y); 89 ask(x,y); 90 end; 91 end.