计蒜客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\n",ans);
146     return 0;
147 }
时间: 2024-10-08 02:47:27

计蒜客NOIP2017提高组模拟赛(五)day1-展览的相关文章

ZROI提高组模拟赛05总结

ZROI提高组模拟赛05总结 感觉是目前为止最简单的模拟赛了吧 但是依旧不尽人意... T1 有一半的人在30min前就A掉了 而我花了1h11min 就是一个简单的背包,我硬是转化了模型想了好久,生生把一个弱智题变成了一个不可做题 最后竟然在转化两次后的模型上以为自己做出来了 这个题比别人多花的1h左右的时间,而且只得到了30分,成为了这场比赛失败的关键因素 T2 依旧是一道简单题 有人20min之内就A掉了 感觉放在CF里最多算一道Div2 D,还是简单的那种 可是我又一次想复杂了 大意就是

提高组模拟赛总结(1)

T1 : 题意:给定一个连续的颜色序列,至多可以去掉k种颜色,问能得到的最大连续单个颜色长度是多少 n <= 10 ^ 5 做法:考试的时候十分斯波,在统计的时候写了线段树统计,实际上根本不用 维护了两个指针表示当前的序列,离散化后用桶维护每一个颜色的数量,如果颜色 <= k + 1就一直加颜色进来,不然就一直移动左指针删除颜色,每次改变某一颜色数量时更新一下最大值就好了 T2: 题意:(实在没办法总结一句话题意了ORZ,总之是个变种的Lis)有 n 个节目,其描述了在 Ti时 刻 Xi号社团

2014-10-18 noip提高组模拟赛(codecomb)[未填]

> <看了一下觉得挺难的...除了T2 T1只想到了找环,> <倍增的思想没有学过,所以看题解看得雨里雾里的(最近真的打算学一下!) T2贪心..很容易看出的 T3感觉题目没有怎么看懂...> <正解居然是树形dp 果然不太会 T4蒟蒻> <我连最小子矩阵都不会求T_T其他更不用说了 虽然没有参加比赛,但感觉自己到不了200(hzwer说没有200应该去参加普及组QAQ) 题目出的挺好的,觉得noip极有可能出现T1T2T3,所以在此mark 而且T1以为是

10-18 noip提高组模拟赛(codecomb)T2贪心

T2:找min:一直找最小的那个,直到a[i]-x+1小于0,就找次小的,以此类推: 求max,也是一样的,一直到最大的那个,直到次大的比之前最大的大,就找次大的: 这个模拟,可以用上priority_queue: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <queue> using namespace std; c

提高组模拟赛总结(3)

貌似是tyvj 2012年的题? T1:给出一个有向无环图,起点为1终点为N,每条边都有一个长度,并且从起点出发能够到达所有的点,所有的点也都能够到达终点.绿豆蛙从起点出发,走向终点. 到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K . 现在绿豆蛙想知道,从起点走到终点的所经过的路径总长度期望是多少? 刚看到题目,歪歪斜斜的每页上都写着'水题'几个字.我横竖睡不着,仔细看了半夜,才从字缝里看出字来,满本都写着一个字是'坑'!" 显然

提高组模拟赛总结(2)

T1: 题意:给定一个01背包,求将背包装到不能再放任何剩余物品的方案数 做法:部分分 F[j][k]表示前i个物品分配j空间,最小没有使用的物品为k的方案数 F[j][k] = Max(F[j-w[i]][k] + a[i], F[j][k]) 实际上并不需要枚举k,显然物品越重其前面必选的物品就越多,能提供的决策就越少,考虑对物品从大到小排序,此时如果取了第i个物品,i+1 .. n必然要被选择到,如果此时剩下的钱刚好放不下i且放得下 i - 1,那就说明 i 就是没有使用的最小的物品,可以

[jzoj]5478.【NOIP2017提高组正式赛】列队

Link https://jzoj.net/senior/#main/show/5478 Description Sylvia 是一个热爱学习的女孩子.       前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为 m.       为了便于管理,教官在训练开始时,按照从前到后,从左到右的顺序给方阵中从 1 到 n × m 编上了号码(参见后面的样例).即:初始时,第 i 行第 j 列的学生的编号是(

【NOIP2017提高组模拟12.10】幻魔皇

题目 幻魔皇拉比艾尔很喜欢斐波那契树,他想找到神奇的节点对. 所谓斐波那契树,根是一个白色节点,每个白色节点都有一个黑色节点儿子,而每个黑色节点则有一个白色和一个黑色节点儿子.神奇的节点对则是指白色节点对. 请问对于深度为n的斐波那契树,其中距离为i的神奇节点对有多少个?拉比艾尔需要你对于1<=i<=2n的所有i都求出答案. 分析 我们找一找每层黑点和白点的规律 |层数|白点数|黑点数| |:-|:---|:----| |1|1|0| |2|0|1| |3|1|1| |4|1|2| |5|2|

【NOIP2017提高组模拟12.10】神炎皇

题目 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对(a,b),若满足a+b<=n且a+b是ab的因子,则成为神奇的数对.请问这样的数对共有多少呢? 分析 设\(gcd(a,b)=d,a'd=a,b'd=b\) 那么\(a'+b'|a'b'd\) 因为\(gcd(a',b')=1\) 所以\(a'+b'|d\). 又因为\((a'+b')d<=n\) 则\(a'+b'=\sqrt n\) 枚举\(a'+b'=i\) \(d就有\dfrac{n}{i^2}种情况\) 因为\(gcd