不知道该给这题贴什么标签了,但是这是一道好题
1.注意这道题的询问是满足区间减法的,我们可以把一个询问拆成两个询问离线搞搞,这个思想在后面会见到
2.分类的思想,这道题的求相同余数看似很烦,实际上我们发现每个数只有10^4,不难发现
当p>=100时,我们可以完全不虚的穷举k,k+p*1,k+p*2……,计算每个数出现的次数
当p<100时,我们完全可以直接记录f[p,k]代表到现在出现的次数
因此这题做法就很明显了

 1 type node=record
 2        x,w,p,k:longint;
 3      end;
 4 
 5 var q:array[0..200010] of node;
 6     a,f2:array[0..100010] of longint;
 7     f1:array[0..100,0..100] of longint;
 8     ans:array[0..100010,0..1] of longint;
 9     mx,j,l,r,p,k,n,m,i,t:longint;
10 
11 procedure swap(var a,b:node);
12   var c:node;
13   begin
14     c:=a;
15     a:=b;
16     b:=c;
17   end;
18 
19 procedure sort(l,r:longint);
20   var i,j,x:longint;
21   begin
22     i:=l;
23     j:=r;
24     x:=q[(l+r) shr 1].x;
25     repeat
26       while q[i].x<x do inc(i);
27       while x<q[j].x do dec(j);
28       if not(i>j) then
29       begin
30         swap(q[i],q[j]);
31         inc(i);
32         dec(j);
33       end;
34     until i>j;
35     if l<j then sort(l,j);
36     if i<r then sort(i,r);
37   end;
38 
39 begin
40   readln(n,m);
41   for i:=1 to n do
42   begin
43     read(a[i]);
44     if mx<a[i] then mx:=a[i];
45   end;
46   for i:=1 to m do
47   begin
48     readln(l,r,p,k);
49     inc(t); q[t].p:=p; q[t].k:=k; q[t].x:=r; q[t].w:=i*2;
50     inc(t); q[t].p:=p; q[t].k:=k; q[t].x:=l-1; q[t].w:=i*2-1;
51   end;
52   sort(1,2*m);
53   t:=1;
54   while q[t].x=0 do inc(t);
55   for i:=1 to n do
56   begin
57     inc(f2[a[i]]);
58     for j:=1 to 100 do
59       inc(f1[j,a[i] mod j]);
60 
61     while q[t].x=i do
62     begin
63       if q[t].p>100 then
64       begin
65         for j:=0 to mx div q[t].p do
66           inc(ans[q[t].w shr 1+q[t].w mod 2,q[t].w mod 2],f2[q[t].p*j+q[t].k]);
67       end
68       else ans[q[t].w shr 1+q[t].w mod 2,q[t].w mod 2]:=f1[q[t].p,q[t].k];
69       inc(t);
70     end;
71   end;
72   for i:=1 to m do
73     writeln(ans[i,0]-ans[i,1]);
74 end.
View Code

 

posted on 2015-04-04 22:34  acphile  阅读(272)  评论(0编辑  收藏  举报