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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

hdu5014 构造b数列使得t最大(小想法)

發布時間:2025/6/17 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu5014 构造b数列使得t最大(小想法) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ?給你一個序列a,他有n+1個數,每個數的范圍是ai >= 0 && a[i] <= n,同時任意兩個數字都是不相同的,就是ai != aj (i!=j),然后讓你構造一個序列b,這個序列的要求與a序列一樣,最后要求構造的b是使 t = (a0 ^ b0) + (a1 ^ b1) + ...+ (an ^ bn)最大。

思路:

? ? ? 一開始想的太簡單了,因為題目要求的是每個數字都只能用一次,一開始我的想法是根據n的奇偶,來單獨處理,處理的時候也是根據每個ai的奇偶來處理的,結果wa了,現在來說下正確的解法吧,這個題目我用的正確解法有點貪心的意思,我們每次先找到一個最大的2^k的數字,這個數字要小于等于n,從它開始枚舉,往兩邊擴,如果不能擴了就找到當前沒有被找出來的最大的那個2^k繼續擴,不怎么好解釋,自己在紙上多寫幾個連續的二進制數,然后模擬下很容易懂的,這里面有一個很容易讓人懷疑的地方就是可能大數的那個方向會有剩余,其實不用擔心這個,不可能有剩余,因為如果以某一個數為中心往兩側擴的話,只要前面擴到頭了,也就是到1了,那么后面一定是mark完的了,因為擴到1相當于自己*2了,也就是2^(k+1)了,要是沒有看懂什么意思,那么就自己找幾個連續的二進制數模擬下就行了。


#include<stdio.h> #include<string.h> #include<stack>#define N 110000 using namespace std;int mark[N]; int num[N] ,Ans[N];int main () {int n ,i ,tmp;while(~scanf("%d" ,&n)){for(i = 0 ;i <= n ;i ++)scanf("%d" ,&num[i]);stack<int>my_sk;tmp = 1;while(1){my_sk.push(tmp);tmp <<= 1;if(tmp > n) break;}memset(mark ,0 ,sizeof(mark));memset(Ans ,0 ,sizeof(Ans));while(!my_sk.empty()){int L = my_sk.top() - 1;int R = L + 1;my_sk.pop();while(1){if(L < 0 || R > n || mark[L] || mark[R])break;mark[L] = mark[R] = 1;Ans[L] = R ,Ans[R] = L;L -- ,R ++;}}__int64 ans = 0;for(i = 0 ;i <= n ;i ++)ans += (__int64)(num[i] ^ Ans[num[i]]); printf("%I64d\n" ,ans);for(i = 0 ;i <= n ;i ++)if(i == n) printf("%d\n" ,Ans[num[i]]);else printf("%d " ,Ans[num[i]]);}return 0; }

總結

以上是生活随笔為你收集整理的hdu5014 构造b数列使得t最大(小想法)的全部內容,希望文章能夠幫你解決所遇到的問題。

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