值域分块,题解网上有。。
根本不会,总是往莫队上去想,但事实上这题询问满足区间可减性,有更简单的方法
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 ",an[i]); 55 return 0; 56 }