hiho 1259 A Math Problem ( 分段dp 數(shù)位dp )

hiho 1259
題目鏈接(K題)

題目大意

給出一個(gè)公式,f(1)=1浓若,對(duì)任意正整數(shù)n有3×f(n)×f(2n+1)=f(2n)×(1+3f(n)),f(2n)<6×f(n)渺杉。
給一個(gè)n和k,設(shè)g( i )=∑(f( j ) mod k=i)( 0<=i<k, 1<=j<=n ) , 求g(0)g(1)...^g(k-1)的值挪钓。
n<=10^18, k是3,5,17,257,65537中的一個(gè)是越。

解答

題目的公式寫的有點(diǎn)嚇人,其實(shí)仔細(xì)觀看或推導(dǎo)前幾項(xiàng)就會(huì)發(fā)現(xiàn)f[2n]=3f[n]和f[2n+1]=3f[n]+1的遞推公式碌上。我先是想打表找規(guī)律倚评,發(fā)現(xiàn)mod 3很快就找到了浦徊,但是mod 5找不到,更何況還有mod更大的天梧。
換個(gè)思路就會(huì)發(fā)現(xiàn)盔性,f(n)的遞推可以分段,分成[1,1]腿倚,[2,3]纯出,[4,7],...敷燎,[2k,2(k+1)-1]暂筝。最多只有l(wèi)ogn個(gè)區(qū)間,對(duì)每個(gè)區(qū)間存mod的余數(shù)的狀態(tài)硬贯,就可以轉(zhuǎn)移焕襟。把[1,n]的區(qū)間分成[1,2k-1]和[2k,n] ( 2^k恰好小于等于n ),做兩次分段dp就可以了( 第二次要注意區(qū)間上界饭豹,記錄區(qū)間最后一個(gè)f(n)取mod的值 )鸵赖。

網(wǎng)上題解有種神奇的做法,推出遞推公式后拄衰,f(n)其實(shí)是把n轉(zhuǎn)化成二進(jìn)制后它褪,1的權(quán)重按三進(jìn)制來算。比如f(5)=10翘悉,5的二進(jìn)制是101茫打,30+32=10。然后直接數(shù)位dp做妖混。
參考blog1
參考blog2

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;

#define bll long long
#define For(i,a,b) for (int i=(a),_##i=(b); i<=_##i; i++)
#define Rof(i,a,b) for (int i=(a),_##i=(b); i>=_##i; i--)
#define Mem(a,b) memset(a,b,sizeof(a))

const int maxL=65537+10;
long long N;
int modd;
long long dp[65][maxL];
long long G[maxL];

void baoli()
{
    static int f[maxL];
    static int gg[maxL];
    Mem(gg,0);
    f[1]=1;
    gg[1]=1;
    for (int i=2; i<=N; i++)
    {
        if (i&1) f[i]=(f[i>>1]*3+1) %modd;
            else f[i]=(f[i>>1]*3) %modd;
        gg[f[i]]++;
    }
    int ans=0;
    For(i,0,modd-1)
        ans^=gg[i];
    printf("%d\n",ans);
}

void Done1(long long *G,long long tt)
{
    Mem(dp,0);
    dp[0][1]=1;
    G[1]++;
    for (int k=1; (1LL<<k)<=tt; k++)
    {
        For(j,0,modd-1)
            if (dp[k-1][j])
            {
                int ss=3*j %modd;
                dp[k][ss]+=dp[k-1][j];
                dp[k][(ss+1)%modd]+=dp[k-1][j];
            }
        For(j,0,modd-1)
            G[j]+=dp[k][j];
    }
}

void Done2(long long *G,long long x,long long y)
{
    static long long low[65],high[65]; // 存每個(gè)區(qū)間的上下界
    static int last_mod[65];        // 記錄區(qū)間最后一個(gè)數(shù)的取mod值
    int k=0;
    low[k]=x,high[k]=y;
    for (long long tt=x>>1; tt; tt>>=1)
    {
        k++;
        low[k]=low[k-1]>>1;
        high[k]=high[k-1]>>1;
    }
    Mem(dp,0);
    last_mod[k]=1;
    dp[k][1]=1;
    for (k--; k>=0; k--)
    {
        For(j,0,modd-1)
            if (dp[k+1][j])
            {
                int ss=3*j %modd;
                dp[k][ss]+=dp[k+1][j];
                dp[k][(ss+1)%modd]+=dp[k+1][j];
            }
        if (!(high[k]&1))
        {
            int ss=(last_mod[k+1]*3+1) %modd;
            dp[k][ss]--;
        }
        last_mod[k]=(last_mod[k+1]*3+(high[k]&1)) %modd;
    }
    For(j,0,modd-1)
        G[j]+=dp[0][j];
}

long long Done()
{
    if (N==1) return 1;
    long long r=1;
    while((r<<1)<=N) r<<=1;
    memset(G,0,sizeof(long long)*(modd+2)); // G[]存余數(shù)的個(gè)數(shù)
    Done1(G,r>>1);         // 計(jì)算從區(qū)間[1,1]到[r/2,r-1]的和
    Done2(G,r,N);          // 計(jì)算[r,N]的和
    long long ans=0;
    For(j,0,modd-1)
        ans^=G[j];
    return ans;
}

int main(int argc, char* argv[])
{
    int zz=0; scanf("%d",&zz);
    For(test,1,zz)
    {
        scanf("%lld%d",&N,&modd);
        bll ans=Done();
        printf("%lld\n",ans);
        //baoli(); // 暴力 驗(yàn)算
    }
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末老赤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子制市,更是在濱河造成了極大的恐慌领追,老刑警劉巖趁蕊,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肢预,警方通過查閱死者的電腦和手機(jī)仔掸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門阔挠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來医舆,“玉大人,你說我怎么就攤上這事振坚∞备椋” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵渡八,是天一觀的道長啃洋。 經(jīng)常有香客問我传货,道長,這世上最難降的妖魔是什么宏娄? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任问裕,我火速辦了婚禮,結(jié)果婚禮上孵坚,老公的妹妹穿的比我還像新娘粮宛。我一直安慰自己,他們只是感情好卖宠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布巍杈。 她就那樣靜靜地躺著,像睡著了一般扛伍。 火紅的嫁衣襯著肌膚如雪筷畦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天刺洒,我揣著相機(jī)與錄音鳖宾,去河邊找鬼。 笑死逆航,一個(gè)胖子當(dāng)著我的面吹牛鼎文,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播因俐,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼漂问,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了女揭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤栏饮,失蹤者是張志新(化名)和其女友劉穎吧兔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袍嬉,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡境蔼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伺通。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箍土。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖罐监,靈堂內(nèi)的尸體忽然破棺而出吴藻,到底是詐尸還是另有隱情,我是刑警寧澤弓柱,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布沟堡,位于F島的核電站侧但,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏航罗。R本人自食惡果不足惜禀横,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粥血。 院中可真熱鬧柏锄,春花似錦、人聲如沸复亏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜓耻。三九已至茫舶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刹淌,已是汗流浹背饶氏。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留有勾,地道東北人疹启。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像蔼卡,于是被迫代替她去往敵國和親喊崖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)雇逞。 張土汪:刷leetcod...
    土汪閱讀 12,744評(píng)論 0 33
  • 下面是培臻教育小編為大家整理的一篇關(guān)于BMAT考試:科學(xué)知識(shí)與應(yīng)用練習(xí)(3)的文章荤懂,供大家參考,下面是詳細(xì)內(nèi)容塘砸。 ...
    peizhenjy閱讀 169評(píng)論 0 0
  • 打起精神來 拼吧 和時(shí)間拼出火花 狠狠的燃燒自己 狠狠的燒 如果我又懈怠 你們一定要噴死我
    金子心閱讀 222評(píng)論 1 2
  • 可能最近是畢業(yè)季掉蔬,很多人難逃畢業(yè)就分手的魔咒廊宪,或者是很多人沒有扛過所謂的水逆,有好多人給我留言或者發(fā)私信女轿,說自己失...
    王大純閱讀 2,629評(píng)論 26 86
  • 乘車途中箭启,兩人嘮嗑(東北話,閑談):有一位老媽媽蛉迹,兒子得了重癥傅寡,治病差(缺少)了一萬元,不知從哪里借來的錢,去醫(yī)院...
    兵雨閱讀 352評(píng)論 0 1