标签:from ber cstring 预处理 ide script query close 复杂
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3432 Accepted Submission(s): 1227
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cstdio> 5 #include<map> 6 using namespace std; 7 8 #define LL long long 9 #define MAXN 100005 10 11 int n; 12 int num[MAXN]; 13 int mn[MAXN]; 14 int dp[MAXN][20]; 15 map<int,LL> res; 16 17 int gcd(int a,int b) 18 { return b==0?a:gcd(b,a%b);} 19 20 void Init() 21 { 22 mn[0]=-1; 23 for (int i=1;i<=n;i++) 24 { 25 mn[i]=((i&(i-1))==0)?mn[i-1]+1:mn[i-1]; 26 dp[i][0]=num[i]; 27 } 28 for (int j=1;j<=mn[n];j++) 29 for (int i=1;i+(1<<j)-1<=n;i++) 30 { 31 dp[i][j]=gcd(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); 32 } 33 } 34 35 int st_calc(int l,int r) 36 { 37 int k = mn[r-l+1]; 38 return gcd(dp[l][k],dp[r-(1<<k)+1][k]); 39 } 40 41 void erfen() 42 { 43 res.clear(); 44 for (int i=1;i<=n;i++) //以i为左起点的区间的所有公约数 45 { 46 int cur = i , gc = num[i]; //用二分求出 47 while (cur <= n) 48 { 49 int l=cur,r=n; 50 while(l<r) 51 { 52 int mid = (l+r+1)>>1; 53 if (st_calc(i,mid)==gc) l=mid; 54 else r = mid -1; 55 } 56 if (res.count(gc)) res[gc]+=l-cur+1; 57 else res[gc]=l-cur+1; 58 cur = l + 1; 59 if (cur<=n) 60 gc = gcd(gc,num[cur]); 61 } 62 } 63 } 64 65 int main() 66 { 67 int t; 68 int cas=0; 69 scanf("%d",&t); 70 while (t--) 71 { 72 scanf("%d",&n); 73 for (int i=1;i<=n;i++) 74 scanf("%d",&num[i]); 75 Init(); 76 77 erfen(); 78 79 int q; 80 scanf("%d",&q); 81 printf("Case #%d:\n",++cas); 82 while (q--) 83 { 84 int x,y; 85 scanf("%d%d",&x,&y); 86 int kk = st_calc(x,y); 87 printf("%d %lld\n",kk,res[kk]); 88 } 89 } 90 return 0; 91 }
标签:from ber cstring 预处理 ide script query close 复杂
原文地址:http://www.cnblogs.com/haoabcd2010/p/6670939.html