HDU 5726--GCD【倍增】【单调栈】【STL-map】
来源:互联网 发布:vb调用matlab的dll 编辑:程序博客网 时间:2024/06/06 02:26
Description
Give you a sequence of N (N≤100,000)integers:a1,…,an(
题目大意就是给一个数列,每次给一个l,r,求出[l,r]的gcd和与[l,r]的gcd相同的区间个数。
题解
第一问很简单吧,直接用倍增搞就好了(类似于ST表的搞法)。
看第二问。首先,这里总共会有多少个不同的gcd的值呢,答案是
这就告诉我们,因为gcd的总数很小,所以可以事先预处理处所有可能出现的gcd的值的答案。问题来了,如何预处理?在预处理时要充分利用gcd的总量很小这一特殊的性质。维护一个栈,表示以某一位为右端点的所有区间中每一种gcd出现的次数,考虑在右边加了一个数,以新数为右端点的序列中的gcd的值就是原来的gcd分别与新数取gcd,别忘了,新加入的数也是gcd的一种情况。至于每种gcd的个数都是很好维护的东西了。
最后,累计答案的时候要用到STL的map(每次刷的时候把以当前为右端点的所有可能情况全部累计到map里)。
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<map>#define maxn 100006#define LL long longusing namespace std;inline char nc(){ static char buf[100000],*i=buf,*j=buf; return i==j&&(j=(i=buf)+fread(buf,1,100000,stdin),i==j)?EOF:*i++;}inline int _read(){ char ch=nc();int sum=0; while(!(ch>='0'&&ch<='9'))ch=nc(); while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc(); return sum;}map<int,LL>res;struct data{ int x; LL num; bool operator <(const data&b)const{return x<b.x;}}stack[maxn],stack1[maxn];int tet,n,m,top,f[maxn][19];int gcd(int x,int y){return !y?x:gcd(y,x%y);}void make_f(){ for(int j=1;j<=log2(n);j++) for(int i=1;i<=n-(1<<j)+1;i++) f[i][j]=gcd(f[i][j-1],f[i+(1<<(j-1))][j-1]);}int get(int l,int r){ int j=log2(r-l+1); return gcd(f[l][j],f[r-(1<<j)+1][j]);}int main(){ freopen("gcd.in","r",stdin); freopen("gcd.out","w",stdout); tet=_read(); for(int t=1;t<=tet;t++){ printf("Case #%d:\n",t); n=_read();res.clear(); for(int i=1;i<=n;i++)f[i][0]=_read(); make_f(); m=_read();top=0; for(int i=1;i<=n;i++){ for(int j=1;j<=top;j++)stack1[j].x=gcd(stack[j].x,f[i][0]),stack1[j].num=stack[j].num; stack1[++top].x=f[i][0];stack1[top].num=1; sort(stack1+1,stack1+1+top); int j=1,top1=top;top=0; while(j<=top1){ int k=j;LL sum=0; while(k<=top1&&stack1[k].x==stack1[j].x)sum+=stack1[k++].num; stack[++top].x=stack1[j].x;stack[top].num=sum;res[stack[top].x]+=stack[top].num; j=k; } } while(m--){ int l=_read(),r=_read(),k=get(l,r); printf("%d %lld\n",k,res[k]); } } return 0;}
阅读全文
0 0
- HDU 5726--GCD【倍增】【单调栈】【STL-map】
- HDU 5726 GCD 倍增
- [HDU 5726] GCD (倍增法+二分)
- HDU 5875 Function(单调栈+在线倍增法)
- HDU 5726-GCD(暴力+map)
- HDU 5726 GCD 区间gcd查询 MAP RMQ 优化
- HDU 3172 (STL map)
- [UVa 1642]Magical GCD STL map遍历
- BZOJ 2286 SDOI2011 消耗战 倍增LCA+单调栈
- bzoj-2286 消耗战【虚树+倍增lca+单调栈】
- Codeforces860E Arkady and a Nobody-men -- 单调栈 + 倍增
- HDU-1263 水果(STL:map)
- 【BZOJ4052】【Cerc2013】Magical GCD 单调栈
- 单调栈——hdu5726 GCD
- hdu 3855 单调栈
- hdu 4923 单调栈
- HDU 4252(单调栈)
- HDU 1506 单调栈
- 左值引用(&)以及右值引用(&&)(原创+转载)
- ACM-Classy
- 自定义布局某个点击区域
- 利用多线程编写多个客户端向服务器并发数据
- tinker(二)-使用TinkerPatch 平台-集成
- HDU 5726--GCD【倍增】【单调栈】【STL-map】
- Android中listview布局,自定义adapter,长按,点击,退出的demo
- LeetCode_200 求海岛数目
- Qt4与Qt5的区别
- golang 接口
- HDU 3008 Warcraft (动态规划)【打怪类】
- 使用flashFXP连接云服务器
- 各种计算机学习的网络课
- 20170715