对于维护a ,c数组有两种方法:
1.对于每个修改,暴力修改c
2.对于每个查询,暴力查找a
第一种方法是for倍数,最坏复杂度可能达到On,第二种则是sqrt(n)
因此普遍情况下选择第二种,但是题给的x是随机的,期望情况下1只要logn,大大节省了时间。
故采用方法1.
考虑到a[x]的变化如何影响某个c[y]。 想要影响c[y]。必须有 a - b - c 。 其中 b = a * x1 , c = b * y1 。 设 c = a * z 。 有 z = x1 * y1 。也就是说变化途径有 d(z) 种。
于是预处出因子个数函数即可。
注意使用快读和输出挂
#pragma warning(disable:4996) #include<iostream> #include<algorithm> #include<bitset> #include<tuple> #include<unordered_map> #include<fstream> #include<iomanip> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<list> #include<queue> #include<stack> #include<sstream> #include<cstdio> #include<ctime> #include<cstdlib> #define pb push_back #define INF 0x3f3f3f3f #define inf 0x7FFFFFFF #define moD 1000000003 #define pii pair<ll,ll> #define eps 1e-8 #define equals(a,b) (fabs(a-b)<eps) #define bug puts("bug") #define re register #define fi first #define se second typedef long long ll; typedef unsigned long long ull; const ll MOD = 1e9 + 7; const int maxn = 1e6 +5; const double Inf = 10000.0; const double PI = acos(-1.0); using namespace std; ll a[maxn]; int readint() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } void Put(ll x) //输出 { if (x > 9) Put(x / 10); putchar(x % 10 + '0'); } int fac[maxn]; int main() { for (int i = 1; i <= maxn - 3; i++) for (int j = i; j <= maxn - 3; j += i) fac[j]++; int n, q; n = readint(); q = readint(); while (q--) { int tmp; tmp = readint(); if (tmp == 1) { int x, y; x = readint(), y = readint(); for (int i = x, j = 1; i <= n; i += x, j++) a[i] +=(ll) y * fac[j]; } else { int c; c = readint(); //printf("%lld ", a[c]); Put(a[c]); puts(""); } } }