zoukankan      html  css  js  c++  java
  • 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
    ",ans[i]&0x7fffffff);
    43     return 0;
    44 }
  • 相关阅读:
    [Luogu5042/UOJ #100][国家集训队互测2015]丢失的题面/ydc的题面
    [51nod1773]A国的贸易
    [GZOI2019&GXOI2019]省选GG记
    [51nod1659]数方块
    [51nod1052]最大M子段和
    [51nod1201]整数划分
    [51nod1084]矩阵取数问题 V2
    [51nod1020]逆序排列
    [BZOJ3000]Big Number
    [BZOJ1684][Usaco2005 Oct]Close Encounter
  • 原文地址:https://www.cnblogs.com/wsy01/p/8324702.html
Copyright © 2011-2022 走看看