Jzoj3895 数字对
来源:互联网 发布:英国大学精算 知乎 编辑:程序博客网 时间:2024/06/06 01:28
给你一个序列s,求出所有最长的区间[l,r]使得存在一个k∈[l,r]且对于任何i∈[l,r]都有s[k]|s[i]
显然如果这个k存在,那么s[k]一定是s[l]~s[r]的最小值
现在问题就成了,求一个最长的区间使得s[l]~s[r]的最小值=s[l]~s[r]的gcd
那么我们可以二分答案,而求一个区间最小和gcd都可以用ST表完成,所以整体复杂度nlg^2n
(虽然说这是solution的方法但是不是最快的方法,最快的方法是枚举k,让后向两边暴力扫描法,复杂度是n^2的但是跑起来非常快!)
正解:313ms
#pragma GCC optimize("O3")#pragma G++ optimize("O3")#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>using namespace std;inline int Min(int a,int b){ return a<b?a:b; }inline int gcd(int a,int b){for(int c;b;a=b,b=c) c=a%b;return a;}int preLog[500010],n,w[500010];vector<int> A;struct ST_list{int (*f)(int,int) ;int g[20][500010];void init(int* s,int (*f1)(int,int) ){f=f1;memcpy(g[0]+1,s+1,n<<2);for(int i=n;i;--i)for(int j=1;i+(1<<j)-1<=n;++j)g[j][i]=f(g[j-1][i],g[j-1][i+(1<<j-1)]);}int query(int l,int r){int k=preLog[r-l+1];return f(g[k][l],g[k][r-(1<<k)+1]);}} s1,s2;bool ok(int len){int M=n-len;for(int i=1;i<=M;++i)if(s1.query(i,i+len)==s2.query(i,i+len)) return 1;return 0;}int main(){preLog[1]=0;for(int i=2,j=0;i<=500010;++i){if(i==(1<<j+1)) ++j;preLog[i]=j;}scanf("%d",&n);for(int i=1;i<=n;++i) scanf("%d",w+i);s1.init(w,Min); s2.init(w,gcd);int l=0,r=n-1;for(int m;l<r;){m=l+r+1>>1;if(ok(m)) l=m;else r=m-1; }n-=l;for(int i=1;i<=n;++i)if(s1.query(i,i+l)==s2.query(i,i+l)) A.push_back(i);printf("%d %d\n",A.size(),l);for(int i=0,z=A.size();i<z;++i) printf("%d ",A[i]);}
暴力:76ms#include<iostream>#include<cstdio>#include<cstdlib>#define fo(i,a,b) for(int i=a;i<=b;i++)#define N 500010using namespace std;int a[N],ans[N];int main(){ int n,num=0,val=0; cin>>n; fo(i,1,n) { scanf("%d",&a[i]); if(a[i]==1) { cout<<1<<' '<<n-1<<endl<<1; return 0; } } fo(k,1,n) { if(a[k]==0) continue; int l=k,r=k; while(a[l-1]%a[k]==0 && l>1) l--; while(a[r+1]%a[k]==0 && r<n) r++; if(r-l==val && l!=ans[num]) ans[++num]=l; if(r-l>val) { fo(i,1,num) ans[i]=0; val=r-l,ans[num=1]=l; } } cout<<num<<' '<<val<<endl; fo(i,1,num) printf("%d ",ans[i]);}
阅读全文
1 0
- Jzoj3895 数字对
- 数字对
- 对数字的检测
- 对数字进行排序
- 对数字的操作
- 7对数字排序
- 7对数字
- 7对数字
- P3862数字对
- 用js对数字验证
- js 对数字的格式化
- Java中对数字格式化
- java对数字进行四舍五入
- JS中对数字四舍五入
- mybatis对数字的处理
- 对数字去重,排序!
- 【noip模拟赛】数字对
- 对数字进行自定义62进制 数字加密 的方法
- 嵌入式多路温湿度监控系统(十一boa网页界面)
- 完整的m序列序列生成函数和调用
- chroot ubuntu 16.04 on android
- 关于数组输入--类似于C那种动态分配数组内存的JAVA解决
- 大数据 第一节课 linux基础 基本的操作
- Jzoj3895 数字对
- Qt定时器的应用,实现时钟的状态
- Gym 101142G Gangsters in Central City【思维+Lca】
- 高级C语言教程-C语言函数setjmp()函数
- bzoj1731 [Usaco2005 dec]Layout 排队布局(差分约束+spfa)
- PHP最常用的设计模式
- Tensorflow实战Google-第三章-简单神经网络
- 【51nod】 1279
- NOIP专题训练——网络流 题解