題意:
給你一棵樹,每個節點上有若干餅乾,並且給出每個節點上吃一塊餅乾需要多少時間,同時給出走過一條邊所需時間。
總時限為 tt,兩個人輪流進行操作:
mitya從當前節點擊擇乙個子節點向下走,或者直接結束遊戲並往根回動吃餅乾;
vasya割斷當前節點到其某個子節點的邊,或者什麼都不做。
問mitya可以吃到的最多的多少塊餅乾。
思路參考:dream_maker_yk的部落格
線段樹維護字首和。
首先我們以時間ti為座標向線段樹中插入節點。儲存兩個值,把子樹吃光所用的總時間sum,子樹中的cookie總數cnt。
然後根據剩餘時間val查詢,如果左子樹的sum比val小,那麼說明左子樹可以吃光,那麼查詢結果就是:
cnt左子樹 + 對右子樹查詢val - sum左子樹
這樣我們就可以用logn的時間實現貪心策略了。
然後 每次就是維護線段樹,維護的是dfs一條鏈的不同餅的和。
#include using namespace std;
#define mo 100005
long long num_x[mo],time_y[mo];
void read(long long a,long long n)
#define mk make_pair
vector< pair> tree[mo];
long long s_tree[mo*40],s_trees[mo*40];
void update(long long pos,long long l,long long r,long long x,long long t)
else if(num>f2)
}update(1,1,1e6,-num_x[node],time_y[node]);
if(node==1) return max(f1,ans);
return max(f2,ans);
}int main()
cout< 題解
#includeusing namespace std ;
const int maxn = 2e5+10;
int n,m,fa[maxn];
struct noe[maxn];
bool cmp(no a , no b)
ans+=p[i]/2;}}
}int main()
}for(int i=0;ielse
}manc.push_back(0);
// cout<<"l r = "/ for(int k=0;kmanacher();
// cout<<"******x "<}
}cout<}
}
cf刷題日誌
e1.send boxes to alice easy version e2.send boxes to alice hard version easy和hard都沒想出來怎麼貪心。首先對於k 1k 1k1 且k1 k2k 1 k 2 k1 k2 可以顯然得到結論1 把所有數組合為k 1k 1 k1...
leetcode 刷題日記
將兩個有序鍊錶合併為乙個新的有序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。採用乙個帶頭節點的指標head鏈結合併後的新指標,乙個空指標pre進行迴圈載入兩個鍊錶中的節點比較兩個鍊錶節點的值,pre指標鏈結較小值的鍊錶的節點,依次遍歷兩個鍊錶,直到乙個為空停止迴圈。複雜度分析 時間複...
leetcode 刷題日記
題目 給出兩個 非空 的鍊錶用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式儲存的,並且它們的每個節點只能儲存 一位 數字。如果,我們將這兩個數相加起來,則會返回乙個新的鍊錶來表示它們的和。您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。解題思路 按照最長鍊錶的長度遍歷兩個...