bzoj 3529 [Sdoi2014]数表
2017-05-12 17:07
399 查看
3529: [Sdoi2014]数表
Time Limit: 10 Sec Memory Limit:512 MB
Submit: 1832 Solved: 922
[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
24 4 3
10 10 5
Sample Output
20148
HINT
1 < =N.m < =10^5 , 1 < =Q < =2×10^4【分析】
有点神啊...莫比乌斯反演+树状数组。
https://wenku.baidu.com/view/fbec9c63ba1aa8114431d9ac.html (Orz PoPoQQQ)
悲伤的发现自己几乎无法做出来一道反演题...(蒟蒻能看懂题解就不错了)
总的来说就是暴力更新的时候不能把整个前缀和数组更新掉,要用一只树状数组维护= =
【代码】
//bzoj 3529 数表
#include<algorithm>
#include<iostream>
#include<cstring>
#include<climits>
#include<cstdio>
#define N 100000
#define p INT_MAX
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int mxn=100005;
int T;
bool vis[mxn];
int n[mxn],m[mxn],c[mxn];
int pri[mxn],miu[mxn],ans[mxn];
struct node {int pos,v;} f[mxn];
struct query {int n,m,a,id;} q[mxn];
inline bool comp_n(node x,node y)
{
return x.v<y.v;
}
inline bool comp_q(query x,query y)
{
return x.a<y.a;
}
inline int read()
{
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;
}
inline void shai()
{
miu[1]=1;
fo(i,2,N)
{
if(!vis[i]) pri[++pri[0]]=i,miu[i]=-1;
for(int j=1;j<=pri[0] && i*pri[j]<=N;j++)
{
vis[i*pri[j]]=1;
if(i%pri[j]==0)
{
miu[i*pri[j]]=0;
break;
}
miu[i*pri[j]]=-miu[i];
}
}
fo(i,1,N)
{
f[i].pos=i;
for(int j=i;j<=N;j+=i)
f[j].v+=i;
}
sort(f+1,f+N+1,comp_n);
}
inline int lowbit(int x) {return x&-x;}
inline void add(int x,int v)
{
for(int i=x;i<=N;i+=lowbit(i))
c[i]+=v;
}
inline int getsum(int x)
{
int sum=0;
for(int i=x;i>0;i-=lowbit(i))
sum+=c[i];
return sum;
}
inline int solve(int n,int m)
{
int tmp=0;
for(int i=1,last=0;i<=n;i=last+1)
{
last=min(n/(n/i),m/(m/i));
tmp+=(n/i)*(m/i)*(getsum(last)-getsum(i-1));
}
return tmp&p;
}
int main()
{
shai();
T=read();
fo(i,1,T)
{
q[i].n=read(),q[i].m=read(),q[i].a=read(),q[i].id=i;
if(q[i].n>q[i].m) swap(q[i].n,q[i].m);
}
sort(q+1,q+T+1,comp_q);
int now=1;
fo(i,1,T)
{
while(now<=N && f[now].v<=q[i].a)
{
for(int j=1;j*f[now].pos<=N;j++)
add(j*f[now].pos,f[now].v*miu[j]);
now++;
}
ans[q[i].id]=solve(q[i].n,q[i].m);
}
fo(i,1,T) printf("%d\n",ans[i]&p);
return 0;
}
相关文章推荐
- bzoj3529 [Sdoi2014]数表
- [BZOJ3529] [SDOI2014] 数表 - 莫比乌斯反演 - 树状数组
- 【BZOJ3529】【SDOI2014】数表
- bzoj 3529: [Sdoi2014]数表
- BZOJ 3529 [Sdoi2014]数表
- BZOJ 3529([Sdoi2014]数表-莫比乌斯反演)
- 【bzoj3529】[Sdoi2014]数表 莫比乌斯反演+离线+树状数组
- 【BZOJ3529】[Sdoi2014]数表 莫比乌斯反演+树状数组
- [莫比乌斯反演+数状数组] BZOJ3529: [Sdoi2014]数表
- 【BZOJ3529】【莫比乌斯反演 + 树状数组】[Sdoi2014]数表
- bzoj3529: [Sdoi2014]数表
- bzoj 3529: [Sdoi2014]数表
- 【bzoj3529】【SDOI2014】【数表】【莫比乌斯反演+树状数组】
- [Sdoi 2014] bzoj3529 数表 [莫比乌斯反演+树状数组]
- bzoj 3529: [Sdoi2014]数表 (反演)
- BZOJ 3529 [Sdoi2014]数表 ——莫比乌斯反演 树状数组
- bzoj 3529 [Sdoi2014]数表(莫比乌斯反演+BIT)
- 莫比乌斯反演套路二--(n/d)(m/d)给提出来--BZOJ3529: [Sdoi2014]数表
- 【BZOJ3529】【SDOI2014】 数表
- bzoj3529[Sdoi2014]数表