zoukankan      html  css  js  c++  java
  • 计蒜客NOIP2017提高组模拟赛(五)day1-展览

    传送门

    发现这题选或不选对状态的优劣程度不会产生影响,如果已经确定了两个数a和b,那么最优的首项和公比也都是唯一确定的,

    与对于后面的数x,加进去也好不加进去也好,首项和公比依旧是原来的

    于是我们用尺取算法,用两个指针来扫一遍,

    如果只有一个数且下一个数能被整除,就加进去,然后确定首项和公比

    如果只有一个数且下一个数不能整除,两个指针直接指向下一个数

    如果有多个数且下一个数满足公式,就加进来

    如果有多个数且下一个数不满足公式,两个指针直接指向下一个数

    这样对于最优解,一定是可以找到的

    顺便说下最优的公比和首项的确定:

    已知两个数x y,求满足它们的最优的首项 公比

    设x=a*q^k1 y=a*q^k2 且x>y

    那么x/y得到q^(k1-k2),

    由于最优的公比一定尽可能小,所以要使指数尽可能大,就把q质因数分解,指数取gcd提出

    这样就得到了公比,拿这个公比不断地除以一开始的x,就得到了首项

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<map>
      7 #include<set>
      8 #include<queue>
      9 #include<vector>
     10 #define INF 0x7f7f7f7f
     11 #define pii pair<int,int>
     12 #define ll long long
     13 #define MAXN 100005
     14 using namespace std;
     15 
     16 ll read(){
     17     ll x=0,f=1;char ch=getchar();
     18     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
     19     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     20     return x*f;
     21 }
     22 int n;
     23 set<ll> s;
     24 ll a[MAXN];
     25 int gcd(int x,int y){
     26     return (y==0?x:gcd(y,x%y));
     27 }
     28 ll Pow(ll x,ll y){
     29     ll ret=1;
     30     while(y){
     31         if(y&1){
     32             ret*=x;
     33         }
     34         x*=x;
     35         y>>=1;
     36     }
     37     return ret;
     38 }
     39 int gt(ll x,ll y,ll &b,ll &q){
     40     ll t=x/y;
     41     if(1==t){
     42         b=x,q=1;
     43         return 1;
     44     }
     45     vector<pii> vs;
     46     for(int i=2;i<=1000;i++){
     47         if(t%i==0){
     48             int cnt=0;
     49             while(t%i==0){
     50                 cnt++;
     51                 t/=i;
     52             }
     53             vs.push_back(make_pair(i,cnt));
     54         }
     55     }
     56     if(t>1000){
     57         return -1;
     58     }
     59     int g=vs[0].second;
     60     for(int i=1;i<vs.size();i++){
     61         g=gcd(g,vs[i].second);
     62     }
     63     q=1;
     64     for(int i=0;i<vs.size();i++){
     65         q*=Pow((ll)vs[i].first,(ll)vs[i].second/g);
     66     }
     67     b=y;
     68     while(b%q==0){
     69         b/=q;
     70     }
     71     return 1;
     72 }
     73 int check(ll x,ll b,ll q){
     74     if(x%b){
     75         return 0;
     76     }
     77     if(q==1){
     78         return (x==b);
     79     }
     80     if(s.count(x)){
     81         return 0;
     82     }
     83     x/=b;
     84     ll t=q;
     85     int L=0,R=log(1.0*x)/log(1.0*q)+3;
     86     while(R-L>1){
     87         int mid=(L+R)/2;
     88         ll t=Pow(q,(L+R)/2);
     89         if(t>=x){
     90             R=mid;
     91         }
     92         else{
     93             L=mid;
     94         }
     95     }
     96     if(Pow(q,L)==x||Pow(q,R)==x){
     97         return 1;
     98     }
     99     return 0;
    100 }
    101 int main()
    102 {
    103 //    freopen("seq2.in","r",stdin);
    104 //    freopen("seq.out","w",stdout);
    105     n=read();
    106     for(int i=1;i<=n;i++){
    107         a[i]=read();
    108     }
    109     int L=1,R=1;
    110     int ans=1;
    111     ll b=0,q=0;
    112     s.insert(a[1]);
    113     for(int i=2;i<=n;i++){
    114         ll t1=a[R],t2=a[i];
    115         if(t1<t2){
    116             swap(t1,t2);
    117         }
    118         if(t1%t2!=0){
    119             s.clear();
    120             s.insert(a[i]);
    121             L=i,R=i;
    122             continue;
    123         }
    124         if(L==R){                
    125             R++;
    126             s.insert(a[R]);
    127             if(-1==gt(t1,t2,b,q)){
    128                 L++;
    129                 s.clear();
    130                 s.insert(a[L]);
    131             }
    132         }
    133         else if(check(a[i],b,q)){
    134             R++;
    135             if(q!=1)
    136                 s.insert(a[R]);
    137         }
    138         else{
    139             s.clear();
    140             s.insert(a[i]);
    141             L=i,R=i;
    142         }
    143         ans=max(ans,R-L+1);        
    144     } 
    145     printf("%d
    ",ans);
    146     return 0;
    147 }
  • 相关阅读:
    阿里云云计算认证ACP模拟考试练习题10套:第1套模拟题分享
    as3+java+mysql(mybatis) 数据自动工具(二)
    自动化登录账号密码并截图保存
    自动化读取csv文件
    自动化读取磁盘文件并逐一在百度上面进行搜索
    自动化打开百度搜索
    python自动化--数据驱动(从文件中提取)
    pycharm 命令行方式
    软件测试工程师 总结
    八大元素定位代码
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7770671.html
Copyright © 2011-2022 走看看