HDU5726 GCD
来源:互联网 发布:彩影软件下载 编辑:程序博客网 时间:2024/05/14 13:44
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726
个人感想: 这道题呢我们在比赛的时候想到过用线段树来处理.可是有个问题的就是我们队伍并不知道该如何去处理查线段树的整个区间的的个数.我队友提出过用合并区间..我觉得不可能啊,怎么合并,类似于这样
因为我已经知道前三个数以4结尾的3个区间,当我新加一个6时,就得和前面求出来的GCD值再求GCD值,然后就得到以6为结尾的前4个区间的GCD的值,每次处理只要用个Set存起来就好了. 可是这样子最差的情况会出现(n^2) 然后我们就直接放弃了..
后来大牛跟我们说绝对不会出现(n^2)的情况,因为求到的GCD值会越来越小,处理出来相同的GCD值合并起来,就可以降低复杂度,!反正不会超过logn就可以处理完..你问我为什么?我也不太情况,个人感觉写了很多种样例都能合并起来,不会有合并不起来的结果,,可能的GCD值只会在这些数得范围内,一旦遇到一个素数,那么前边的区间必定都成1了,肯定能合并起来,,如果没有素数,就算全是偶数,反正也不会超过logn,至于证明我就不太会了,,毕竟是个渣渣,如果有哪位大牛可以告诉我下那就更好了..
对了记得要全部换成long long 才行,不换long long 是过不了的,可是我觉得以题目的数据范围,int绝对可以了队友说,可能是int 的值接近爆炸时 取余的时候会出现问题..–可能成立吧,我倒没试过,暂时只能这样理解了
分析:线段树+预处理
代码:
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * *///#define OUT#include <iostream>using namespace std;#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <sstream>#include <cctype>#include <vector>#include <set>#include <cstdlib>#include <map>#include <queue>//#include<initializer_list>//#include <windows.h>//#include <fstream>//#include <conio.h>#define MaxN 0x7fffffff#define MinN -0x7fffffff#define Clear(x) memset(x,0,sizeof(x))const int INF=0x3f3f3f3f;const int maxn=1e5+10;typedef long long ll;ll T;ll N;ll Q;ll X[maxn];map<ll,ll> Set;map<ll,ll> temp;map<ll,ll> Cou;class QLR{public: ll L; ll R;};QLR qlr[maxn];class Node{public: ll l; ll r; ll w;};Node node[4*maxn];ll gcd(ll a,ll b){ if(b==0)return a; return gcd(b,a%b);}void Build_Tree(ll l,ll r,ll k){ node[k].l=l; node[k].r=r; if(l==r) { node[k].w=X[l]; return; } ll mid=(l+r)/2; Build_Tree(l,mid,2*k); Build_Tree(mid+1,r,2*k+1); node[k].w=gcd(node[2*k].w,node[2*k+1].w); return;}ll Search_Tree(ll l,ll r,ll k){ ll a=0; ll b=0; if(l<=node[k].l&&node[k].r<=r) { return node[k].w; } ll mid=(node[k].l+node[k].r)/2; if(l<=mid) { a=Search_Tree(l,min(mid,r),2*k); } if(r>mid) { b=Search_Tree(max(mid+1,l),r,2*k+1); } return gcd(a,b);}int main(){#ifdef OUT freopen("coco.txt","r",stdin); freopen("lala.txt","w",stdout);#endif ll cas=0; scanf("%I64d",&T); while(T--) { Cou.clear(); temp.clear(); Set.clear(); cas++; printf("Case #%I64d:\n",cas); scanf("%I64d",&N); for(ll i=1;i<=N;i++) { scanf("%I64d",&X[i]); } Build_Tree(1,N,1); scanf("%I64d",&Q); for(ll i=1;i<=Q;i++) { scanf("%I64d%I64d",&qlr[i].L,&qlr[i].R); } for(ll i=1;i<=N;i++) { temp.clear(); for(map<ll,ll>::iterator it=Cou.begin();it!=Cou.end();it++) { ll t=(*it).first; ll k=gcd(t,X[i]); temp[k]+=Cou[t]; } Cou.clear(); for(map<ll,ll>::iterator it=temp.begin();it!=temp.end();it++) { Cou[(*it).first]=temp[(*it).first]; } for(map<ll,ll>::iterator it=Cou.begin();it!=Cou.end();it++) { Set[(*it).first]+=Cou[(*it).first]; } Set[X[i]]+=1; Cou[X[i]]+=1; } for(ll i=1;i<=Q;i++) { ll k=Search_Tree(qlr[i].L,qlr[i].R,1); printf("%I64d %I64d\n",k,Set[k]); } } return 0;}
0 0
- HDU5726 GCD
- hdu5726 GCD
- hdu5726 GCD
- HDU5726 GCD
- HDU5726-GCD
- HDU5726 GCD【RMQ+二分】
- hdu5726 GCD 多校1
- Hdu5726:GCD—题解
- hdu5726 GCD(gcd +二分+rmq)
- hdu5726 GCD(二分+RMQ)
- hdu5726 - GCD (RMQ + 二分)
- hdu5726 GCD(map+线段树)
- hdu5726 GCD st表 + 二分
- hdu5726 GCD ST表+离线
- hdu5726 GCD (线段树+区间gcd)
- hdu5726 多校1 GCD【rmq+二分】
- hdu5726 GCD+ST表 by:lethalboy
- RMQ -ST ——hdu5726 GCD
- Cpp环境【Usaco2.1.3】【Vijos1222】顺序排分数
- mac下 iterm2配色方案
- codeforces-57C Array(找规律+逆元)
- redis的pconnect解析
- zynq Nand flash,QSPI,EMMC接口
- HDU5726 GCD
- Android事件分发机制(三)事件分发和消费
- The method setCharacterEncoding(String) is undefined for the type HttpServle
- destoon 上传多张照片,出现后面的图片上传不了解决办法
- jmap,jhat分析内存
- LintCode(容易)二进制求和
- 汇总常用的jQuery操作Table tr td方法
- Android activity lifecycle
- urlencode 和 urldecode