You are given a 1-indexed array of size N. Initially, all elements of the array are zeros. You need to perform U updates to the array.
Each Update asks you to add 1 to the elements of the array at the indices specified by 'ax+b' for all non-negative integers x, where a and b are positive integers which specify an update query.
After performing all the updates to the array, print the array with every entry separated by space.
Input
First Line of the input contains 2 space separated integers N, U.
Each of the next U lines contains 2 space-separated integers: a and b, specifying an update.
Output
Output the array in a single line after all updates.
Constraints
- 1 ≤ N ≤ 105
- 1 ≤ a, b ≤ N
- 1 ≤ U ≤ 2*105
Example
Input: 7 4 1 3 7 7 7 3 2 2 Output: 0 1 2 2 1 2 2
Explanation
Array after first update : [0,0,1,1,1,1,1]
Array after second update : [0,0,1,1,1,1,2]
Array after third update : [0,0,2,1,1,1,2]
Array after fourth update : [0,1,2,2,1,2,2]
题意:给你一个长度为n的数组(初始为0)u次增加 增加的条件是 ax+b<=n(x=0,1,2,3,.....)ax+b计算的值就是相应数组的的下标如果ax+b<=n 那就arr[ax+b]++;
解题思路:首先看u和 a,b,n的范围 有1e5 所以暴力肯定会T 所以采取分块策略。一般分块就是sqrt(n)本题也可以采用此策略 定义一个二维数组 ma[i][j] i表示基数a 表示基数b 首先处理 当 a>sqrt(n)直接算 否则就ma[a][b]++; 再看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int sum[maxn];
int ma[320][maxn];
int main()
{
int n,u,a,b;
scanf("%d%d",&n,&u);
int block=sqrt(n);
while(u--)
{
scanf("%d%d",&a,&b);
if(a<=block) ma[a][b]++;
else
for(int i=b;i<=n;i+=a)
sum[i]++;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=block;j++)
{
sum[i]+=ma[j][i];
if(i+j<=n)
ma[j][i+j]+=ma[j][i];
}
}
for(int i=1;i<=n;i++)
printf("%d%c",sum[i],i==n? '\n':' ');
return 0;
}