BZOJ3529: [Sdoi2014]数表 莫比乌斯反演_树状数组
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #include <cstdio> #include <algorithm> #include <cstring> #define ll long long #define setIO(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) const long long mod = 2147483648; const long long N = 100008; const int maxn = 100009 ; using namespace std; struct M{ int delta; int id; }opt[maxn]; int prime[maxn],tot,vis[maxn],mu[maxn],g[maxn],answer[maxn]; int cmp2(M a,M b){ return a.delta < b.delta; } void Init(){ mu[1] = 1; for ( int i=2;i < maxn; ++i) { if (!vis[i]) prime[++tot] = i, mu[i] = -1; for ( int j=1;j <= tot && (ll)i * prime[j] <= N; ++j) { vis[i * prime[j]] = 1; if (i % prime[j]==0) { mu[i * prime[j]] = 0; break ; } mu[i*prime[j]]=-mu[i]; } } for ( int i=1;i<maxn;++i) for (ll j=1;(ll)j*i<=N;++j) g[i*j] += i; for ( int i=1;i<maxn;++i) opt[i].delta=g[i],opt[i].id=i; sort(opt+1,opt+maxn,cmp2); } struct BIT{ ll C[maxn]; int lowbit( int t) { return t & (-t); } void update( int x,ll k) { while (x < maxn) { C[x]+=k, C[x]%=mod; x+=lowbit(x); } } ll query( int x){ ll sum=0; while (x>0) sum+=C[x],sum%=mod,x-=lowbit(x); return sum; } }tree; ll work( int n, int m, int p) { if (n>m) swap(n,m); long long sum=0; for ( int i=1,j;i <= n;i=j+1) { j=min(n/(n/i),m/(m/i)); sum+=(n/j)*(m/j)*(tree.query(j)-tree.query(i-1)); sum%=mod; } return sum; } struct P{ int n,m,a,id; }node[maxn]; int cmp(P a,P b){ return a.a<b.a; } void oper( int p){ for ( int i=1;i*opt[p].id<=N;++i) tree.update(opt[p].id*i,((ll)opt[p].delta*mu[i]+mod)%mod); } int main(){ //setIO("input"); Init(); int T; scanf ( "%d" ,&T); for ( int i=1;i<=T;++i) scanf ( "%d%d%d" ,&node[i].n,&node[i].m,&node[i].a),node[i].id=i; sort(node+1,node+1+T,cmp); int last=1; for ( int i=1;i<=T;++i) { int j=last; while (opt[j].delta <= node[i].a) oper(j),++j; last=j; answer[node[i].id]=( int )work(node[i].n,node[i].m,node[i].a); } for ( int i=1;i<=T;++i) printf ( "%d\n" ,(answer[i]+mod)%mod); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步