码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3529[Sdoi2014]数表

时间:2018-01-21 17:30:31      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:date   problem   blog   col   script   printf   com   limit   scan   

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]数表

标签:date   problem   blog   col   script   printf   com   limit   scan   

原文地址:https://www.cnblogs.com/wsy01/p/8324702.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!