Sum Of Gcd HDU
来源:互联网 发布:java字符串转数组对象 编辑:程序博客网 时间:2024/05/17 01:31
Given you a sequence of number a 1, a 2, …, a n, which is a permutation of 1…n.
You need to answer some queries, each with the following format:
Give you two numbers L, R, you should calculate sum of gcd(a[i], a[j]) for every L <= i < j <= R.
Input
First line contains a number T(T <= 10),denote the number of test cases.
Then follow T test cases.
For each test cases,the first line contains a number n(1<=n<= 20000).
The second line contains n number a 1,a 2,…,a n.
The third line contains a number Q(1<=Q<=20000) denoting the number of queries.
Then Q lines follows,each lines contains two integer L,R(1<=L<=R<=n),denote a query.
Output
For each case, first you should print “Case #x:”, where x indicates the case number between 1 and T.
Then for each query print the answer in one line.
Sample Input
1
5
3 2 5 4 1
3
1 5
2 4
3 3
Sample Output
Case #1:
11
4
0
把自己蠢哭了,智障去每次去dfs一个数的因子,直接预处理存起来不就好了嘛,预处理第一个询问居然直接去暴力,对自己无语啊。。。
优化版:
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<bitset>#include<vector>#define N 20500#define INF 10000000000#define mod 1000000007using namespace std;typedef long long ll;vector<int> factor[20005];int phi[N];void init(){ for(int i=0;i<N;i++) phi[i]=i; for(int i=2;i<N;i++) { if(phi[i]==i) { for(int j=i;j<N;j+=i) phi[j]-=phi[j]/i; } } for(int i=1;i<=20000;i++) for(int j=i;j<=20000;j+=i) factor[j].push_back(i);}int block[N];struct node{ int l,r; int index;}query[N];ll ans[N];int a[N];int cmp(node x1,node x2){ if(block[x1.l]==block[x2.l]) return x1.r<x2.r; return block[x1.l]<block[x2.l];}int cnt[N];int curL,curR;ll curAns;void add(int x){ for(int i=0;i<factor[x].size();i++) { int num=factor[x][i]; curAns+=phi[num]*cnt[num]; cnt[num]++; }}void sub(int x){ for(int i=0;i<factor[x].size();i++) { int num=factor[x][i]; cnt[num]--; curAns-=phi[num]*cnt[num]; }}void work(int L,int R){ while(curL<L) { sub(a[curL]); curL++; } while(curL>L) { curL--; add(a[curL]); } while(curR>R) { sub(a[curR]); curR--; } while(curR<R) { curR++; add(a[curR]); }}int main(){ init(); int t,n; scanf("%d",&t); int cal=1; while(t--) { memset(cnt,0,sizeof(cnt)); scanf("%d",&n); int limit=(int)sqrt(n); for(int i=1;i<=n;i++) block[i]=(i-1)/limit; for(int i=1;i<=n;i++) scanf("%d",a+i); int m; scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&query[i].l,&query[i].r); query[i].index=i; } sort(query+1,query+1+m,cmp); curAns=0; for(int i=query[1].l;i<=query[1].r;i++) add(a[i]); ans[query[1].index]=curAns; curL=query[1].l; curR=query[1].r; for(int i=2;i<=m;i++) { work(query[i].l,query[i].r); ans[query[i].index]=curAns; } printf("Case #%d:\n",cal++); for(int i=1;i<=m;i++) printf("%lld\n",ans[i]); } return 0;}
智障的版本:
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<bitset>#include<vector>#define N 20500#define INF 10000000000#define mod 1000000007using namespace std;typedef long long ll;vector<int> prime;int phi[N];void init(){ for(int i=0;i<N;i++) phi[i]=i; for(int i=2;i<N;i++) { if(phi[i]==i) { prime.push_back(i); for(int j=i;j<N;j+=i) phi[j]-=phi[j]/i; } }}int block[N];struct node{ int l,r; int index;}query[N];int ans[N];int a[N];int cmp(node x1,node x2){ if(block[x1.l]==block[x2.l]) return x1.r<x2.r; return block[x1.l]<block[x2.l];}int gcd(int a,int b){ return a%b==0?b:gcd(b,a%b);}int cnt[N];int curAns,curL,curR;int fac[100];int e[100];int k;void getFac(int x){ k=0; for(int i=0;prime[i]*prime[i]<=x;i++) { if(x%prime[i]==0) { fac[k]=prime[i]; e[k]=0; while(x%prime[i]==0) { x/=prime[i]; e[k]++; } k++; } } if(x>1) { fac[k]=x; e[k]=1; k++; }}int state;void dfs(int cur,int temp){ if(cur==k) { //cout<<temp<<endl; if(state==0) { cnt[temp]--; curAns-=phi[temp]*cnt[temp]; } else { curAns+=phi[temp]*cnt[temp]; cnt[temp]++; } return ; } dfs(cur+1,temp); int c=temp; for(int i=1;i<=e[cur];i++) { c*=fac[cur]; dfs(cur+1,c); }}void dfs2(int cur,int temp){ if(cur==k) { cnt[temp]++; return ; } dfs2(cur+1,temp); int c=temp; for(int i=1;i<=e[cur];i++) { c*=fac[cur]; dfs2(cur+1,c); }}void work(int L,int R){ while(curL<L) { state=0; getFac(a[curL]); dfs(0,1); curL++; } while(curL>L) { state=1; curL--; getFac(a[curL]); dfs(0,1); } while(curR>R) { state=0; getFac(a[curR]); dfs(0,1); curR--; } while(curR<R) { state=1; curR++; getFac(a[curR]); dfs(0,1); }}int main(){ init(); int t,n; scanf("%d",&t); int cal=1; while(t--) { memset(cnt,0,sizeof(cnt)); scanf("%d",&n); int limit=(int)sqrt(n); for(int i=1;i<=n;i++) block[i]=(i-1)/limit; for(int i=1;i<=n;i++) scanf("%d",a+i); int m; scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&query[i].l,&query[i].r); query[i].index=i; } sort(query+1,query+1+m,cmp); curAns=0; for(int i=query[1].l;i<=query[1].r;i++) { getFac(a[i]); dfs2(0,1); for(int j=i+1;j<=query[1].r;j++) curAns+=gcd(a[i],a[j]); } ans[query[1].index]=curAns; curL=query[1].l; curR=query[1].r; for(int i=2;i<=m;i++) { work(query[i].l,query[i].r); //cout<<curL<<" "<<curR<<endl; /*for(int i=1;i<=5;i++) cout<<cnt[i]<<" "; cout<<endl;*/ ans[query[i].index]=curAns; } printf("Case #%d:\n",cal++); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0;}
- Sum Of Gcd HDU
- HDU 5381 The sum of gcd
- hdu 5381 The sum of gcd
- hdu 5381 The sum of gcd
- HDU 5381The sum of gcd
- HDU 5381 The sum of gcd
- HDU 5381 The sum of gcd
- HDU 5381 The sum of gcd
- hdu 5381 The sum of gcd(线段树+gcd)
- HDU4676 Sum Of Gcd
- Sum Of Gcd
- hdu5381The sum of gcd
- hdu4676 Sum Of Gcd
- HDU 4676 Sum Of Gcd【数论,数据结构(分块)】
- 莫比乌斯反演 hdu 4676 Sum Of Gcd
- hdu 5381 The sum of gcd 莫队 + DP
- HDU 5381 The sum of gcd 莫队暴力
- HDU 5381 The sum of gcd 离线处理+线段树
- console对应的使用方法
- 备份测试的测试点
- 06-面向对象(抽象类-特点) 06-面向对象(抽象类-特点)2 06-面向对象(抽象类-特点)3
- 我的Linux学习之路(五、安装Nginx)
- No unique bean of type [com.yuanv.backstage.dao.SysUserDao] is defined: expected single matching bea
- Sum Of Gcd HDU
- hibernate 使用总结
- MindManager 2018维恩图如何修改背景模板
- paypal如何获取API签名
- 使用Spring配置管理Quartz的时候会遇到下面的异常:
- Ubuntu16.04操作系统的安装
- 设计模式——策略模式
- subsys_system_register 会在/sys/devices/system下面建立一个目录
- vmware fusion 创建多个Ubuntu16