【JZOJ 3623】【SDOI2014】数表
2017-03-07 21:16
253 查看
Description
Solution
本题为看到gcd上反演系列,设fd表示能整除d的自然数总和,
Ans=∑i=1n∑j=1mfgcd(i,j)
反演的套路就不写了,
Ans=∑T=1min(n,m)⌊nT⌋⌊mT⌋∑d|Tfd∗μ(Td)
有因为有f的大小限制,这个只能得部分分,
正解是离线,按f的限制排序,
再把f排序,
设sn=∑d|nμ(nd)fd[fd<=a]
每次限制变大,就会有一些新的f符合要求,
设fi现在变得符合要求,
那么,影响到的s就只有是i的倍数的s,
就是sd=sd+fi(d|i),
这个不停枚举d的过程是O(nlog(n))
有因为要分块,要做s的前缀和,
所以就用树状数组。
复杂度:O(nlog(n)2+Q∗(n−−√+m−−√)∗log(n))
PS:祝君卡常愉快!
分块的时候注意尽量不要用(LL)/(LL),超级慢。
Code
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define min(q,w) ((q)<(w)?(q):(w)) #define NX(q) ((q)&(-(q))) using namespace std; typedef long long LL; const int N=200500; LL mo=1073741824; int read(int &n) { char ch=' ';int q=0,w=1; for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar()); if(ch=='-')w=-1,ch=getchar(); for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n; } int m,n; int f ; LL Ans ; bool prz ; int pr ,mu ; struct qqww { LL v;int n; }b ; struct qwqw { int n,m,K,i; }sc ; int c ,g ; bool cz ; LL sum ; void ss(int I,int q,LL e) { f[q]=e; fo(i,I,pr[0]) { LL t=1; LL t1=e; bool z=1; while(1) { t*=pr[i]; t1=(t1+e*t); if(t*q>n)break; if(t1>1e9){printf("swddwdw %lld\n",t*q); break;} ss(i+1,t*q,t1); z=0; } if(z)break; } } bool PX(qqww q,qqww w){return q.v<w.v;} bool PXsc(qwqw q,qwqw w){return q.K<w.K;} void add(int q,LL w){for(;q<=n;q+=NX(q))f[q]+=w;} LL Gsum(int q) { // return 1; LL ans=0; for(;q>0;q-=NX(q))ans+=f[q]; return ans; } LL fk(int n,int m) { int i=1; LL ans=0; while(i<=n) { LL nx=min(n/(n/i),m/(m/i)); ans=(ans+(LL)(n/i)*((LL)m/i)*(Gsum(nx)-Gsum(i-1)))%mo; i=nx+1; } return ans; } int main() { freopen("table.in","r",stdin); freopen("table.out","w",stdout); int q,w; mo*=2; n=1e5+10; mu[1]=1; fo(i,2,n) { if(!prz[i])pr[++pr[0]]=i,mu[i]=-1; fo(j,1,pr[0]) { LL t=pr[j]*i; if(t>n)break; prz[t]=1; if(i%pr[j]==0)break; mu[t]=-mu[i]; } } ss(1,1,1); f[n+1]=2e9; fo(i,1,n+1)b[i].v=f[i],b[i].n=i,f[i]=0; sort(b+1,b+1+n,PX); int _; read(_); fo(i,1,_) { read(sc[i].n),read(sc[i].m),read(sc[i].K),sc[i].i=i; if(sc[i].n>sc[i].m)swap(sc[i].n,sc[i].m); } sort(sc+1,sc+1+_,PXsc); q=1; fo(i,1,_) { while(b[q].v<=sc[i].K) { int t=b[q].n,cs=b[q].v; int jn=n/t; fo(j,1,jn)if(mu[j])add(j*t,cs*mu[j]); q++; } Ans[sc[i].i]=(fk(sc[i].n,sc[i].m)+mo)%mo; } fo(i,1,_)printf("%lld\n",Ans[i]); return 0; }
相关文章推荐
- jzoj 3623【SDOI2014】数表(table)
- 【jzoj3623】【SDOI2014】【数表】【莫比乌斯反演】
- [SDOI2014][JZOJ3624]数数
- 【BZOJ】3529: [Sdoi2014]数表
- [莫比乌斯反演+数状数组] BZOJ3529: [Sdoi2014]数表
- [SDOI 2014] [JZOJ 3625] 旅行
- 【jzoj3625】【SDOI2014】【旅行(travel)】 【虚树】【lct】
- JZOJ 3600. 【CQOI2014】通配符匹配
- 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)
- jzoj 3597. 【CQOI2014】危桥
- JZOJsenior5536.【2014东莞市选】游戏
- jzoj 5535. 【2014东莞市选】登机 dp
- BZOJ3531: [Sdoi2014]旅行
- 【BZOJ 3531】 [Sdoi2014]旅行
- 【汕头市选2014】分叉 jzoj 3630 dfs
- 【JZOJ3664】【SHTSC2014】三叉神经树(neuron) (树链剖分 or LCT)
- BZOJ 3529 [Sdoi2014]数表 【莫比乌斯反演】
- 【时光回溯】【JZOJ3566】【GDKOI2014】阶乘
- jzoj. 3929. 【NOIP2014模拟11.6】创世纪
- [BZOJ3530][SDOI2014]数数(AC自动机+数位dp)