題目:
水果店裡有 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;
}
方法2:還是線段樹,這次線段樹維護的是最大的sum[i],從1開始,如果根節點大於tot(一開始是0),那就說明以1開始有大於0的某段,找出下標最大的大於tot的,一直迴圈到n,每次迴圈tot+=a[i]#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;
**
#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次數越多,那麼最後的結果就越大,而最後的結果顯然和最多能取多少次最大值,還有想要取的那個數的深度有關,如果最大值的深度小於可以取最大值的次數,那麼就能取到,如果最大值的深度小於可以取最大值的次數,那...