bzoj2506 calc

值域分块,题解网上有。。

根本不会,总是往莫队上去想,但事实上这题询问满足区间可减性,有更简单的方法

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 #define fi first
 7 #define se second
 8 #define mp make_pair
 9 #define pb push_back
10 typedef long long ll;
11 typedef unsigned long long ull;
12 typedef pair<int,int> pii;
13 struct Q
14 {
15     int l,p,k,tp,nm;
16 }q[201000];
17 bool operator<(const Q &a,const Q &b)
18 {
19     return a.l<b.l;
20 }
21 int n,m,nq;
22 int a[101000],an[101000];
23 int ma[101][101],ma2[10100];
24 void add(int p)
25 {
26     for(int i=1;i<=100;i++)
27         ma[i][a[p]%i]++;
28     ma2[a[p]]++;
29 }
30 int main()
31 {
32     int i,j,l,r,p,k,tt;
33     scanf("%d%d",&n,&m);
34     for(i=1;i<=n;i++)    scanf("%d",&a[i]);
35     for(i=1;i<=m;i++)
36     {
37         scanf("%d%d%d%d",&l,&r,&p,&k);
38         q[++nq].l=l-1;q[nq].p=p;q[nq].k=k;q[nq].tp=-1;q[nq].nm=i;
39         q[++nq].l=r;q[nq].p=p;q[nq].k=k;q[nq].tp=1;q[nq].nm=i;
40     }
41     sort(q+1,q+nq+1);
42     for(i=1,j=0;i<=nq;i++)
43     {
44         while(j+1<=q[i].l)    add(++j);
45         if(q[i].p<=100)    an[q[i].nm]+=q[i].tp*ma[q[i].p][q[i].k];
46         else
47         {
48             tt=0;
49             for(k=q[i].k;k<=10000;k+=q[i].p)
50                 tt+=ma2[k];
51             an[q[i].nm]+=q[i].tp*tt;
52         }
53     }
54     for(i=1;i<=m;i++)    printf("%d\n",an[i]);
55     return 0;
56 }
View Code

 

posted @ 2018-09-27 12:39  hehe_54321  阅读(114)  评论(0编辑  收藏  举报
AmazingCounters.com