日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客练习赛37 C 筱玛的迷阵探险(Trie+折半)

發布時間:2023/12/8 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客练习赛37 C 筱玛的迷阵探险(Trie+折半) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:

筱瑪的迷陣探險

?

題意:

一個n×n的矩陣A,每個格子上有一個有一個數Ai,j。入口在左上角的(1,1)處,出口在右下角的(n,n)處。每一步都只能向下或向右移動一格。最后能獲得的經驗值為初始經驗e與路徑上經過的所有數的權值異或和。求筱瑪最大可能獲得的經驗值。

?

思路:

如果純暴力,dfs整張圖,復雜度O(2^(2n)),數量級最壞情況下為O(2^40),肯定會TLE。

但如果只暴力搜半張圖,最壞為O(2^20),時間沒有問題。因此,我們先從(1,1)開始dfs暴力遍歷上半張圖(上半部分,以對角線(從右上到左下)為分割線),對角線上的每個點開一棵字典樹,存到這個點的所有可能情況。然后我們再從(n,n)開始暴力遍歷下半張圖,每當搜到對角線上的點時就去該字典樹上求異或最大值(復雜度O(logk)= 31,k為字典樹節點個數),取所有最大值中的最大值。

總復雜度O(2^20 * logk)

注意:字典樹的空間大小盡可能大,這題有毒......

?

Code:

#include <bits/stdc++.h> using namespace std;typedef long long ll;const int MAX = 5e6+10;int n; ll e; ll mp[25][25]; int tree[25][MAX][2]; int tot=0; ll ans=0;void add(int id,ll x) {int root=0;for(int i=30;i>=0;i--){int p=(x>>i)&1;if(!tree[id][root][p]) tree[id][root][p]=++tot;root=tree[id][root][p];} }ll query(int id,ll x) {int root=0;ll val=0;for(int i=30;i>=0;i--){int p=(x>>i)&1;if(tree[id][root][p^1]){val+=(1ll<<i);root=tree[id][root][p^1];}else{root=tree[id][root][p];}}return val; }void dfs1(int x,int y,int step,ll val) {if(step==n){add(x,val^mp[x][y]);return;}if(y+1<=n) dfs1(x,y+1,step+1,val^mp[x][y]);if(x+1<=n) dfs1(x+1,y,step+1,val^mp[x][y]); }void dfs2(int x,int y,int step,ll val) {if(step==n){ans=max(ans,query(x,val));return;}if(y-1>=1) dfs2(x,y-1,step+1,val^mp[x][y]);if(x-1>=1) dfs2(x-1,y,step+1,val^mp[x][y]); }int main() {scanf("%d%lld",&n,&e);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%lld",&mp[i][j]);tot=0;ans=0;dfs1(1,1,1,e);dfs2(n,n,1,0);printf("%lld\n",ans);return 0; }

?

總結

以上是生活随笔為你收集整理的牛客练习赛37 C 筱玛的迷阵探险(Trie+折半)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。