热身训练2 GCD
2024-10-19 12:44:02
简要题意:
n个数字,a1,a2,...,an
m次询问(l,r),每次询问需回答 1.gcd(al,al+1,al+2,...,ar);2.gcd(ax,ax+1,ax+2,...,ay)=gcd(al,al+1,al+2,...,ar)的个数(x<=y)。
分析:
算第一个询问,由于a数组是静态的,我们可以用ST表来预处理。
对于第二个询问,我们先令左端点x固定,那么随着y的增加,gcd(ax,...,ay)会越来越小,这是可以二分的!!!
这样看来,我们完全可以预处理出每个gcd所有的个数!!!
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define LL long long
const int N=1e5+5;
int gcd(const int a, const int b)
{
if(b == 0) return a;
return gcd(b, a%b);
}
int f[N][30], lg[N], n;
inline void ST_init()
{
for(re i=1;i<=20;++i)
for(re j=1;j+(1<<i)-1 <= n; ++j)
f[j][i] = gcd(f[j][i-1], f[j+(1<<(i-1))][i-1]);
}
inline int gtgcd(const int x, const int y)
{
int k=lg[y-x+1];
return gcd(f[x][k], f[y-(1<<k)+1][k]);
}
inline void work()
{
scanf("%d",&n);
for(re i=1;i<=n;++i) scanf("%d",&f[i][0]);
ST_init();
map<int, long long>mp;
for(re i=1;i<=n;++i)
{
int p=i, tmp = f[i][0];
while(p <= n)
{
int ret=-1, L=p, R=n;
while(L <= R)
{
int mid=(L+R)>>1;
if(gtgcd(i, mid) == tmp) ret=mid, L=mid+1;
else R=mid-1;
}
mp[tmp] += ret-p+1;
p = ret+1;
tmp = gtgcd(i, p);
}
} int m; scanf("%d",&m);
while(m--)
{
int x, y, g;
scanf("%d%d",&x,&y);
g = gtgcd(x, y);
printf("%d %lld\n", g, mp[g]);
}
}
signed main()
{
for(re i=2;i<=100000;++i) lg[i] = lg[i>>1]+1;
int T; scanf("%d",&T);
for(re i=1;i<=T;++i)
{
printf("Case #%d:\n", i);
work();
}
return 0;
}
最新文章
- Windows 搭建jdk、Tomcat、eclipse以及SVN、maven插件开发环境
- Android 不一样的原生分享
- PDO和消息队列的一点个人理解
- sql2014 新建用户并登陆
- [terry笔记]RMAN综合学习之恢复
- struct timespec 和 struct timeval
- Android_Intent_passValueForResult
- JavaScript基础(二)
- C# 6 与 .NET Core 1.0 高级编程 - 37 章 ADO.NET
- 统一代码风格工具——editorConfig
- windows server 2012 + sql server 2008 r2安装
- 【转】嵌入式C语言调试开关
- 自学Zabbix3.10.1-事件通知Notifications upon events-媒介类型
- Android 官方命令深入分析之Android Debug Bridge(adb)
- Java list.remove( )方法需要注意的地方
- 移植 Qt 至 tiny210 详细过程
- DL_WITH_PY系统学习(第2章)
- java.lang.IllegalMonitorStateException异常
- adb INSTALL_FAILED_UPDATE_INCOMPATIBLE
- Asp.Net Core使用System.Drawing.Common部署到docker报错问题