HGOI 20190310 题解

Posted ljc20020730

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HGOI 20190310 题解相关的知识,希望对你有一定的参考价值。

/*
又是又双叒叕WA的一天...
我太弱鸡了...
今天上午打了4道CF
*/

Problem 1 meaning

给出q组询问,求下列函数的值$ f(a) = maxlimits_{0 < b < a} {   gcd(aoplus b,a & b)} $

对于100%的数据 $qleq 1000, 2 leq a_i leq 2^{25}-1$

结论题,直接打表找结论,发现当$a in [2^{n-1},2^{n}-2] (n geq 2)$ 答案为$2^{n} - 1$

当$a = 2^n - 1 ,n geq 1$时答案为a除自己外最大的约数。

直接打表处理26个特殊情况,实际程序复杂度$ O(q) $

技术图片
# include <bits/stdc++.h>
using namespace std;
int a[27],Pow[27];
int fun(int x)
{
    if (x==0) return 0;
    for (int i=1;i<=26;i++)
         if (x==Pow[i]-1) return a[i];
    int i; 
    for (i=1;i<=26;i++) 
        if (x<=Pow[i]-2) break;
    return  Pow[i]-1;
}
int main()
{
    a[1]=0; a[2]=1; a[3]=1; a[4]=5; a[5]=1;
    a[6]=21; a[7]=1; a[8]=85; a[9]=73; a[10]=341;
    a[11]=89; a[12]=1365; a[13]=1; a[14]=5461;
    a[15]=4681; a[16]=21845; a[17]=1; a[18]=87381;a[19]=1;
    a[20]=349525; a[21]=299593; a[22]=1398101; a[23]=178481;
    a[24]=5592405; a[25]=1082401; a[26]=22369621;
    int n ;scanf("%d",&n);
    Pow[0]=1;
    for (int i=1;i<=26;i++) Pow[i]=Pow[i-1]*2;
    int ans;
    while(n--) {
        int x;scanf("%d",&x);
        printf("%d
",fun(x));
    }
    return 0;
}
meaning.cpp

Problem 2 Jongmah

给出n个数字在[1,m]内,构成若干个合法三元组,合法的定义是三元组内元素相同或连续。

对于100%的数据,$ n,mleq 10^6 $

考虑一个dp,先记录每个数出现几次,作为cnt[]数组

考虑若连续三元组超过2个,那么就可以转化为3个相同的三元组,所以在计算中,连续三元组最多为2个。

其他的就被计算在不连续的三元组内。

f[i][k][l]值小于i的所有数,三元组(i,i+1,i+2)选取k$kin [0,2]$,三元组(i-1,i,i+1)选取l个$l in [0,2]$ 最多合法三元组个数。

考虑从f[i-1][l][j]转移过来,枚举 j $ in [0,2]$,转移。

当前状态和前继状态比较在原来基础上多出来k个连续三元组(i,i+1,i+2),到此为止,已经用去

数 i-1 消耗 l+j 个; 数 i-2 消耗 j 个 ; 数 i 消耗 k+j+l个 ; 数 i+1 消耗 k+l ;数 i+2 消耗k个。

$ f[i-1][l][j] + k +  left lfloor frac{cnt[i] - k - j - l}{3} ight floor $

初始化全是0

 

技术图片
# include<bits/stdc++.h>
# define fp(i,s,t) for(int i=s;i<=t;i++)
using namespace std;
const int N=1e6+10;
int f[N][4][4],cnt[N];
int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    int t;
    fp(i,1,n) scanf("%d",&t),cnt[t]++;
    int ans=0;
    fp(i,1,m) fp(k,0,2) fp(l,0,2) fp(j,0,2)
    {
        if(k+j+l>cnt[i]) continue;
        if(l+j>cnt[i-1]) continue;
        if(j>cnt[i-2]) continue;
        if(k+l>cnt[i+1]) continue;
        if(k>cnt[i+2]) continue; 
        f[i][k][l]=max(f[i][k][l],f[i-1][l][j]+k+(cnt[i]-k-j-l)/3);
        ans=max(ans,f[i][k][l]); 
    } 
    cout<<ans<<
;
    return 0;
 }
Jongmah.cpp

 

以上是关于HGOI 20190310 题解的主要内容,如果未能解决你的问题,请参考以下文章

HGOI 20190828 题解

HGOI 20191106 题解

HGOI 20190303 题解

HGOI20181030 模拟题解

hgoi#20191115

hgoi#20190514