牛客網小白月賽D

2021-09-25 05:49:27 字數 2791 閱讀 2472

題目:

水果店裡有 n個水果排成一列。店長要求顧客只能買一段連續的水果。小陽對每個水果都有乙個喜愛程度 ai,最終的滿意度為他買到的水果的喜歡程度之和。如果和為正(不管是正多少只要大於 0 即可),他就滿意了。小陽想知道在他滿意的條件下最多能買多少個水果。

你能幫幫他嗎?

輸入描述:

第一行輸入乙個正整數 n,表示水果總數。

第二行輸入 n 個整數 ai,表示小陽對每個水果的喜愛程度。

輸出描述:

一行乙個整數表示結果。(如果 1 個水果都買不了,請輸出 0)

思路1:樹狀陣列(不知道為什麼線段樹超時),維護字首和sum[i],先離散化,不然sum[i]很大,從1開始update,找到離散化後的下標,把他代表的值更新為min(原值,傳入值i),每次對i查詢時只要查詢小於他的sum[i],這樣sum[i]-sum[j]就能大於0,在所有小於他的j裡找到最小的,所以樹狀陣列維護的是最小值

**

#include #include #include #include using namespace std;

const int n = 4111111;

const int inf = (1<<31)-2;

int a[n],sum[n],b[n],tree[n],n;

void add(int u,int v)

int getmin(int u)

int main()

sort(sum+1,sum+1+n);

int len = unique(sum+1,sum+1+n) - sum-1;

int x = lower_bound(sum+1,sum+1+len,0) - sum;

add(x,0);

int mx = 0;

for(int i = 1 ; i <= n ; i ++)

cout << mx << endl;

return 0;

}

用線段樹的超時**

#include #include #include #include using namespace std;

const int n = 222222;

const int inf = (1<<31)-2;

int a[n],sum[n],b[n];

struct tree

q[n*4];

void push_up(int n)

void built(int n,int l,int r)

int mid = (l+r)>>1;

built(n<<1,l,mid);

built(n<<1|1,mid+1,r);

push_up(n);

}void update(int n,int pos,int num)

int mid = (q[n].l+q[n].r)>>1;

if(pos<=mid)

update(n<<1,pos,num);

else

update(n<<1|1,pos,num);

push_up(n);

}int query(int n,int l,int r)

int mid = (q[n].l+q[n].r)>>1;

if(r<=mid)

return query(n<<1,l,r);

else if(l>mid)

return query(n<<1|1,l,r);

else

}int main()

sort(sum+1,sum+1+n);

int len = unique(sum+1,sum+1+n) - sum-1;

int x = lower_bound(sum+1,sum+1+len,0) - sum;

built(1,0,len+1);

update(1,x,0);

int mx = 0;

for(int i = 1 ; i <= n ; i ++)

cout << mx << endl;

return 0;

方法2:還是線段樹,這次線段樹維護的是最大的sum[i],從1開始,如果根節點大於tot(一開始是0),那就說明以1開始有大於0的某段,找出下標最大的大於tot的,一直迴圈到n,每次迴圈tot+=a[i]

**

#include using namespace std;

const int n = 2e6 + 10;

int a[n], s[n];

int n, ans, l, r, tot;

int mx[n << 2];

void pushup(int rt)

void build(int rt, int l, int r)

int mid = l + r >> 1;

build(rt << 1, l, mid);

build(rt << 1 | 1, mid + 1, r);

pushup(rt);

}int query(int rt, int l, int r)

int main()

build(1, 1, n);

ans = 0;

cout << tot << endl;

for(int i = 1; i <= n; ++i)

ans = max(ans, query(1, 1, n) - i + 1);

tot += a[i];

}printf("%d\n", ans);

return 0;

}

牛客網 小白月賽 D題

位運算是乙個非常重要的東西。而小a最近在學習位運算,小a看到了一道很簡單的例題,是說從n個數裡面選出n 1個數要讓它們或起來的值最大,小a想知道這個答案是多少。你可以幫幫他嗎?輸入描述 第一行乙個整數n表示有n個數接下來一行n個數表示a1,a2 an第一行乙個整數n表示有n個數接下來一行n個數表示a...

牛客小白月賽13 D題

位運算是乙個非常重要的東西。而小a最近在學習位運算,小a看到了一道很簡單的例題,是說從n個數裡面選出n 1個數要讓它們或起來的值最大,小a想知道這個答案是多少。你可以幫幫他嗎?思路 預處理了一下字首l陣列和字尾r陣列,然後列舉那個不選的數就可以了,每次更新ans max ans,l i 1 r i ...

牛客小白月賽29 D 種樹

d 種樹 很久沒來水部落格了,來水一下部落格 這個題目一開始還不知道怎麼寫但是仔細想了一下我們用max次數越多,那麼最後的結果就越大,而最後的結果顯然和最多能取多少次最大值,還有想要取的那個數的深度有關,如果最大值的深度小於可以取最大值的次數,那麼就能取到,如果最大值的深度小於可以取最大值的次數,那...