NYOJ 士兵殺敵系列

2021-08-19 08:23:02 字數 4371 閱讀 8457

時間限制:

1000 ms  |  記憶體限制:

65535 kb

難度:3描述

南將軍手下有n個士兵,分別編號1到n,這些士兵的殺敵數都是已知的。

小工是南將軍手下的軍師,南將軍現在想知道第m號到第n號士兵的總殺敵數,請你幫助小工來回答南將軍吧。

注意,南將軍可能會問很多次問題。輸入

只有一組測試資料

第一行是兩個整數n,m,其中n表示士兵的個數(1

輸出對於每乙個詢問,輸出總殺敵數

每個輸出佔一行

樣例輸入

5 2

1 2 3 4 5

1 32 4

樣例輸出

6

9

思路: 

使用字首和,o(n)預處理,o(1) 查詢

**:

#include#define for(a,b,c) for(int a = b; a <= c; a++)

int sum[1000005];

int main()

while(m--)

return 0;

}

時間限制:

1000 ms  |  記憶體限制:

65535 kb

難度:5描述

南將軍手下有n個士兵,分別編號1到n,這些士兵的殺敵數都是已知的。

小工是南將軍手下的軍師,南將軍經常想知道第m號到第n號士兵的總殺敵數,請你幫助小工來回答南將軍吧。

南將軍的某次詢問之後士兵i可能又殺敵q人,之後南將軍再詢問的時候,需要考慮到新增的殺敵數。輸入

只有一組測試資料

第一行是兩個整數n,m,其中n表示士兵的個數(1

輸出對於每次查詢,輸出乙個整數r表示第m號士兵到第n號士兵的總殺敵數,每組輸出佔一行

樣例輸入

5 6

1 2 3 4 5

query 1 3

add 1 2

query 1 3

add 2 3

query 1 2

query 1 5

樣例輸出

688

20

思路:使用一維樹狀陣列,o(n*log(n)) 預處理,o(1)查詢,o(log(n)) 修改。

**:

#include#define for(a,b,c) for(int a = b; a <= c; a++)

int tree[1000005];

int n, m;

int lowbit(int x)

int sum(int a)

return sum;

}void add(int pos, int num)

}int main()

char s[10];

while(m--)

return 0;

}

時間限制:

2000 ms  |  記憶體限制:

65535 kb

難度:5描述

南將軍統率著n個士兵,士兵分別編號為1~n,南將軍經常愛拿某一段編號內殺敵數最高的人與殺敵數最低的人進行比較,計算出兩個人的殺敵數差值,用這種方法一方面能鼓舞殺敵數高的人,另一方面也算是批評殺敵數低的人,起到了很好的效果。

所以,南將軍經常問軍師小工第i號士兵到第j號士兵中,殺敵數最高的人與殺敵數最低的人之間軍功差值是多少。

現在,請你寫乙個程式,幫小工回答南將軍每次的詢問吧。

注意,南將軍可能詢問很多次。輸入

只有一組測試資料

第一行是兩個整數n,q,其中n表示士兵的總數。q表示南將軍詢問的次數。(1

輸出對於每次詢問,輸出第m號士兵到第n號士兵之間所有士兵殺敵數的最大值與最小值的差。

樣例輸入

5 2

1 2 6 9 3

1 22 4

樣例輸出

1

7

思路:線段樹,o(nlog(n)) 預處理,log(n)查詢,t了。

改用更快的rmq,o(nlog(n)) 預處理,o(1)查詢。

超時**(線段樹):

#include#define for(a,b,c) for(int a = b; a <= c; a++)

#define mem(a,b) memset(a,b,sizeof(a))

#define max(a,b) (a > b ? a : b)

#define min(a,b) (a < b ? a : b)

long long max[400005], min[400005];

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

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

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

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

max[rt] = max(max[rt<<1], max[rt<<1|1]);

min[rt] = min(min[rt<<1], min[rt<<1|1]);

}long long query_max(int ql, int qr, int l, int r, int rt)

long long query_min(int ql, int qr, int l, int r, int rt)

int main()

return 0;

}

rmq:

#include#include#define for(a,b,c) for(int a = b; a <= c; a++)

#define mem(a,b) memset(a,b,sizeof(a))

#define max(a,b) (a > b ? a : b)

#define min(a,b) (a < b ? a : b)

int n, q;

long long max[100005][25], min[100005][25];

void rmq()

}}int main()

rmq();

int a, b;

while(q--)

void add(int num, int pos)

int query(int pos)

int main()

else

}return 0;

}

——————————————————————————————————

時間限制:

2000 ms  |  記憶體限制:

65535 kb

難度:5描述

南將軍麾下有百萬精兵,現已知共有m個士兵,編號為0~m,每次有任務的時候,總會有一批編號連在一起人請戰(編號相近的人經常在一塊,相互之間比較熟悉),最終他們獲得的軍功,也將會平分到每個人身上,這樣,有時候,計算他們中的哪乙個人到底有多少軍功就是乙個比較困難的事情。

在這樣的情況下,南將軍卻經常會在許多次戰役之後詢問軍師小工第i號士兵到第j號士兵所有人的總軍功數。

請你幫助軍師小工回答南將軍的提問。輸入

只有一組測試資料

第一行是三個整數n,c,q(1<=n,c,q<=1000000),其中n表示士兵的總數。

隨後的c行,每行有三個整數mi,ni,ai(0<=mi<=ni<=n,0<=ai<=100),表示從第mi號到第ni號士兵所有人平均增加了ai的軍功。

再之後的q行,每行有兩個正正數m,n,表示南將軍詢問的是第m號士兵到第n號士兵。

輸出請對每次詢問輸出m號士兵到第n號士兵的總軍功數,由於該數值可能太大,請把結果對10003取餘後輸出

樣例輸入

5 3 2

1 3 2

2 4 1

5 5 10

1 52 3

樣例輸出

19

6

思路:離線查詢要取餘,所以使用類似樹狀陣列區間修改的操作。

**:

#include#includeusing namespace std;

#define for(a,b,c) for(int a = b; a <= c; a++)

#define ll long long

int n, c, q;

int v[1000005];

int main()

for(i,1,n) v[i] += v[i-1];

for(i,1,n) v[i] += v[i-1], v[i] %= 10003;

while(q--)

return 0;

}

NYOJ 士兵殺敵(二)

時間限制 1000 ms 記憶體限制 65535 kb 難度 5 描述 南將軍手下有n個士兵,分別編號1到n,這些士兵的殺敵數都是已知的。小工是南將軍手下的軍師,南將軍經常想知道第m號到第n號士兵的總殺敵數,請你幫助小工來回答南將軍吧。南將軍的某次詢問之後士兵i可能又殺敵q人,之後南將軍再詢問的時候...

NYOJ 士兵殺敵 (樹狀陣列)

首先看一道題 描述南將軍手下有n個士兵,分別編號1到n,這些士兵的殺敵數都是已知的。小工是南將軍手下的軍師,南將軍經常想知道第m號到第n號士兵的總殺敵數,請你幫助小工來回答南將軍吧。南將軍的某次詢問之後士兵i可能又殺敵q人,之後南將軍再詢問的時候,需要考慮到新增的殺敵數。輸入 只有一組測試資料 第一...

NYOJ119 士兵殺敵(三)

題目分析 這道題用的rmq演算法 range maximum minimum query 這裡做了幾點優化。1 定義dpmax和dpmin時,為什麼17寫在前面,因為記憶體中資料是按行連續的存的,所以初始化dpmax 0 和dpmin 0 相關資料時,可以直接用memcpy。2 所有的求2的方冪的操...