码迷,mamicode.com
首页 > 其他好文 > 详细

HGOI 20190310 题解

时间:2019-03-10 17:29:18      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:ide   连续   class   特殊   break   mic   sans   出现   splay   

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

Problem 1 meaning

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

对于100%的数据 $q\leq 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\n",fun(x));
    }
    return 0;
}
meaning.cpp

Problem 2 Jongmah

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

对于100%的数据,$ n,m\leq 10^6 $

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

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

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

f[i][k][l]值小于i的所有数,三元组(i,i+1,i+2)选取k$k\in [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} \right \rfloor $

初始化全是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<<\n;
    return 0;
 }
Jongmah.cpp

 

HGOI 20190310 题解

标签:ide   连续   class   特殊   break   mic   sans   出现   splay   

原文地址:https://www.cnblogs.com/ljc20020730/p/10505975.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!