Codeforces 282E. Sausage Maximization【trie樹(非指標版)】

來源:互聯網
上載者:User

標籤:acm   c++   codeforces   資料結構   

題目大意:

給出一串數,pre[i](前i個數的異或)為a[0]~a[i-1]的異或,post[i](尾碼的異或)為a[i]~a[n-1]的異或,求pre[i]^post[j]的最大值(0<=i<=j<=n),其中,pre[0]=0,post[n]=0(表示一個數都不選)。


做法:利用trie樹將尾碼或者首碼儲存起來,首先從pre[n]開始,往前遍曆,對於每個首碼,將此時的尾碼添加到trie樹中,再在trie中尋找與當前首碼異或之後能得到最大的值。在trie中儲存數的時候,將該數的二進位的數位的每一位存進去,由於異或之後不可能增加位元,那麼我們要找最大的值的話,只需要從第一位開始,保證這一位能為1的時候取一,如果不能取一則取0,那麼最後的結果一定是最大的。這裡用的trie樹是非指標版的。。自己寫的,覺得指標太複雜(自己太弱....),用儲存節點下標的方式。
注意儲存數的時候,需要將40位全部存進去(2^40是大於10^12的第一個二次冪數),不然處理位元會很麻煩。這樣的話,trie樹中節點數最多也就40*10^5個,也是可行的。由於數的範圍是10^12,會爆int,得用long long ,還得特別小心特別小心!像(1<<40)這樣的操作是會爆int的,必須寫成這樣(1LL<<40)才行。博主在這裡被坑了好久。。要不是大牛提醒的話,我都不知道什麼時候才能發現這個問題。。。推掉重寫也是有可能的!。。。
詳細見代碼和注釋:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#define N 100010using namespace std;struct node{    long long nxt[2];//儲存nxt節點在數組中的下標}trie[N*40];long long all_idx,bit[42],num[N],n;long long createNode(){    memset(trie[all_idx].nxt,-1,sizeof(trie[all_idx].nxt));//沒有訪問過的置為-1    return all_idx++;}void insert_Node(long long root,long long cur){    memset(bit,0,sizeof(bit));//儲存cur的位元    long long len=0;    while(cur)    {        bit[len++]=cur&1;        cur>>=1;    }    long long idx=root;    //將40位全部存進去    for(len=40;len>=0;len--)    {        long long k=bit[len];        if(trie[idx].nxt[k]==-1)            trie[idx].nxt[k]=createNode();        idx=trie[idx].nxt[k];    }}long long running(long long root,long long cur){    long long sum=0;    memset(bit,0,sizeof(bit));    long long len=0;    while(cur)    {        bit[len++]=cur&1;        cur>>=1;    }    long long idx=root;    for(len=40;len>=0;len--)    {        long long k=!bit[len];/////兩個數不相同,異或結果為1        if(trie[idx].nxt[k]!=-1) {            sum+=(1LL<<len);///////一定要加LL,被坑了好久。。。也是無語了            idx=trie[idx].nxt[k];        }        else idx=trie[idx].nxt[!k];//如果不存在這樣的數,只能取0,並且從這邊走下去。    }    return sum;}int main(){    scanf("%I64d",&n);    long long pre=0,post=0;    long long ans=0;    for(long long i=0;i<n;i++)        scanf("%I64d",num+i),pre^=num[i];    long long root=createNode();    for(long long i=n-1;i>=0;pre^=num[i],post^=num[i],i--)    {        insert_Node(root,post);        ans=max(ans,running(root,pre));    }    ans=max(ans,running(root,pre));//判斷取0個首碼的時候的值    cout<<ans<<endl;    return 0;}


Codeforces 282E. Sausage Maximization【trie樹(非指標版)】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.