zoj 3887 LCGCDS
2015-07-31 18:08
239 查看
题意:求a和b序列中连续区间的gcd相同的最大区间长度以及对应的相等对数
解法:
1.先求出gcd为x的区间的最大长度和最短长度
2.按照x从小到大排序,再按照lmax从大到小排序,然后用二维尺取法求得最终答案即可。
解法:
1.先求出gcd为x的区间的最大长度和最短长度
2.按照x从小到大排序,再按照lmax从大到小排序,然后用二维尺取法求得最终答案即可。
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<vector> #include<math.h> #define Mod mod #define ll long long using namespace std; const int maxn = 100000+10; int n,m,a[maxn],b[maxn]; const int mod = 998244353; int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } struct no{ int lmax,lmin,x; bool operator<(const no &rhs)const{ if(x!=rhs.x) return x<rhs.x; return lmax>rhs.lmax; } }q1[maxn*30],q2[maxn*30]; int tot1,tot2,nxt[maxn]; ll ans1,ans2; void fenjie(int a[],int n,no q[],int &tot){//得到gcd区间 tot=0; int val[maxn]; q[tot++]=(no) { 1,1,a[1] }; nxt[1]=1,val[1]=a[1]; for(int i=2;i<=n;i++){ nxt[i]=i,val[i]=a[i]; int pos=i; while(pos>0){ val[pos]=gcd(val[pos],a[i]); while(nxt[pos]>1&&gcd(val[nxt[pos]-1],val[pos])==val[pos]){ nxt[pos]=nxt[nxt[pos]-1]; } q[tot++]=(no){ i-nxt[pos]+1,i-pos+1,val[pos] }; pos=nxt[pos]-1; } } sort(q,q+tot); } void solve(){//二维尺取法 ans1=ans2=0; for(int i=0,j=0;i<tot1&&j<tot2;){ bool flag=false; ll tmp=0,num1=0,num2=0; if(q1[i].x<q2[j].x) i++; else if(q1[i].x>q2[j].x) j++; else{ if(q1[i].lmax<q2[j].lmin) j++; else if(q1[i].lmin>q2[j].lmax) i++; else{ if(q1[i].lmax>=q2[j].lmin&&q1[i].lmax<=q2[j].lmax){ tmp=q1[i].lmax,flag=true,num1=1,num2=1; while(i+1<tot1&&q1[i+1].x==q1[i].x&&q1[i+1].lmax>=q1[i].lmax) { num1++; i++; } while(j+1<tot2&&q2[j+1].x==q2[j].x&&q2[j+1].lmax>=q1[i].lmax){ if(q2[j+1].lmin<=q1[i].lmax) num2++; j++; } } else if(q2[j].lmax>=q1[i].lmin&&q2[j].lmax<=q1[i].lmax){ tmp=(long long)q2[j].lmax,flag=true,num1=1ll,num2=1ll; while(j+1<tot2&&q2[j+1].x==q2[j].x&&q2[j+1].lmax>=q2[j].lmax) { num2++; j++; } while(i+1<tot1&&q1[i+1].x==q1[i].x&&q1[i+1].lmax>=q2[j].lmax){ if(q1[i+1].lmin<=q2[j].lmax) num1++; i++; } } } } if(flag){ if(tmp>ans1) { ans1=tmp,ans2=num1*num2; } else if(tmp==ans1) { ans2=ans2+num1*num2; } while(i+1<tot1&&q1[i+1].x==q1[i].x) i++; while(j+1<tot2&&q2[j+1].x==q2[j].x) j++; i++,j++; } } printf("%lld %lld\n",ans1,ans2); } int main(){ //freopen("a.txt"< 4000 /span>,"r",stdin); while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int j=1;j<=m;j++) scanf("%d",&b[j]); fenjie(a,n,q1,tot1); fenjie(b,m,q2,tot2); solve(); } return 0; }
相关文章推荐
- 【读书笔记】UIFont-动态下载系统提供的字体-官方代码
- ftrace的使用
- Z-WIFI+openWRT
- [转]115个Java面试题和答案——终极列表(下)
- 流媒体协议介绍
- Android手机Root授权原理细节全解析
- Field 'ssl_cipher' doesn't have a default value
- 字符串中各单词的翻转
- surfaceview
- oc字符串的处理—01
- ,从头天晚上吃过晚饭至早晨,已空腹12小时之久
- Linux TCP 链接状态
- 使用 ftrace 调试 Linux 内核,第 3 部分
- python 之 分割参数getopt
- android防止重复点击事件的发生笔记
- [转]115个Java面试题和答案——终极列表(上)
- CS281: Advanced Machine Learning 第二节 information theory 信息论
- java缓存(4、memcached)
- ios--NSCalendar NSDateComponents
- sql优化之加limit