bzoj3529[Sdoi2014]数表

Posted wsy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3529[Sdoi2014]数表相关的知识,希望对你有一定的参考价值。

3529: [Sdoi2014]数表

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 2294  Solved: 1166
[Submit][Status][Discuss]

Description

    有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为
能同时整除i和j的所有自然数之和。给定a,计算数表中不大于a的数之和。

Input

    输入包含多组数据。
    输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据。

Output

    对每组数据,输出一行一个整数,表示答案模2^31的值。

Sample Input

2
4 4 3
10 10 5

Sample Output

20
148

HINT

 

1 < =N.m < =10^5  , 1 < =Q < =2×10^4

 

Source

Round 1 Day 1

 1 #include<bits/stdc++.h>
 2 #define reg register
 3 #define N 100001
 4 using namespace std;
 5 int cas,pos,now,cnt,ans[N],c[N],mo[N],p[N],vis[N];
 6 struct query{int n,m,a,id;}q[N];struct info{int v,p;}f[N];
 7 bool cmp1(info a,info b){return a.v<b.v;}
 8 bool cmp2(query a,query b){return a.a<b.a;}
 9 void update(int x,int v){while(x<N){c[x]+=v;x+=x&-x;}}
10 int query(int x){int ret=0;while(x){ret+=c[x];x-=x&-x;}return ret;}
11 int main(){
12     mo[1]=1;
13     for(reg int i=2;i<N;++i){
14         if(!vis[i]){p[++cnt]=i;mo[i]=-1;}
15         for(reg int j=1;j<=cnt&&p[j]*i<N;++j){
16             vis[p[j]*i]=1;
17             if(i%p[j])mo[i*p[j]]=-mo[i];
18             else{mo[i*p[j]]=0;break;}
19         }
20     }
21     for(reg int i=1;i<N;++i){
22         for(reg int j=i;j<N;j+=i)
23         f[j].v+=i;f[i].p=i;
24     }
25     sort(f+1,f+N,cmp1);
26     scanf("%d",&cas);
27     for(reg int i=1;i<=cas;q[i].id=i,++i)
28     scanf("%d%d%d",&q[i].n,&q[i].m,&q[i].a);
29     sort(q+1,q+1+cas,cmp2);++now;
30     for(reg int c=1;c<=cas;++c){
31         while(now<N&&f[now].v<=q[c].a){
32             for(reg int i=f[now].p;i<N;i+=f[now].p)
33             update(i,f[now].v*mo[i/f[now].p]);
34             ++now;
35         }
36         int id=q[c].id,n=q[c].n,m=q[c].m;if(n>m)swap(n,m);
37         for(int reg i=1;i<=n;i=pos+1){
38             pos=min(n/(n/i),m/(m/i));
39             ans[id]+=(n/i)*(m/i)*(query(pos)-query(i-1));
40         }
41     }
42     for(int i=1;i<=cas;i++)printf("%d\n",ans[i]&0x7fffffff);
43     return 0;
44 }

 

 

以上是关于bzoj3529[Sdoi2014]数表的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3529: [Sdoi2014]数表

BZOJ3529: [Sdoi2014]数表

BZOJ3529: [Sdoi2014]数表

bzoj3529: [Sdoi2014]数表

bzoj 3529: [Sdoi2014]数表

[BZOJ3529][Sdoi2014]数表