數列(字首和,離散化)

2021-08-22 07:23:01 字數 1440 閱讀 8338

p1667 數列

給定乙個長度是n的數列a,我們稱乙個數列是完美的,當且僅當對於其任意連續子串行的和都是正的。現在你有乙個操作可以改變量列,選擇乙個區間[x,y]滿足ax +ax+1 +…+ ay<0,1輸入格式:

第一行乙個數n,以下n個數。

【資料規模】

對於20%的資料,滿足1≤n≤5;

對於100%的資料,滿足1≤n≤10^5; 1≤|a[i]|≤2^31-1。

輸出格式:

乙個數表示最少的操作次數,如果無解輸出-1。

輸入樣例#1:複製

5

13-3

-4-5

62

輸出樣例#1:複製

2
【樣例解釋】

首先選擇區間[2,4],之後數列變成1,9,-4,7,50,然後選擇[3,3],數列變成1,5,4,3,50

題解:這個題目看上去很難下手。。。

但是,我們不妨對操作表示一下。假設σ(i=x,y)a[i]=ss,則:

+ss -ss..... -ss +ss

ax-1,ax,……,ay,ay+1

假設1~i的字首和為s[i],則:s[x-1]+=ss,s[x]不變,s[y]-=ss,s[y+1]不變,而s[x-1]+ss=s[y],不難發現,操作以後,相當於僅僅交換了s[x-1]和s[y]!而題目中要使所有連續子段和都大於0,說明最後要使字首和遞增!我們發現,無論怎麼操作,字首和的值是不會改變的,只是順序變換了。所以,如果某乙個字首和不為正,那麼最後肯定無解。或者,如果原序列某兩個字首和相等(比如s[u]和s[v](u下面是ac**

//#include#include #include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define ll long long

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

const int inf = 0x3f3f3f3f;

const int onf = -0x3f3f3f3f;

const int mod = 998244353;

const int maxn = 2e4+5;

const int n = 1e5+5;

const double pi = 3.141592653589;

const double e = 2.718281828459;

struct dd

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

return 0;

}

字首和 離散化

現在正在上課,但我還是要同步更新博文。滑稽 先講乙個離散化,就是把幾個離的特別遠的數在不影響結果的情況下,變成相近的數。倒是沒什麼影響,但應用在陣列下標的話可以節約空間。貌似和hash有點像 直接拍 給定n個數,如果乙個數出現x次,則對答案的貢獻為x 2 求這n個數對答案的貢獻是多少。n 10000...

離散化系列 離散化 字首和 差分

區間和 acwing 802.區間和 這道題所展現的情況就是,資料並不是很多,利用到的元素值也不大,但關鍵就是下標太大,無法正常的以陣列下標來進行操作。因此,離散化,在這裡就是很合適了,把大的下標對映為小的下標後再進行處理。對於這道題的解題步驟具體可分為一下幾步 1.儲存,就是將所用用到的下標存起來...

區間和(離散化 二分 字首和)

假定有乙個無限長的數軸,數軸上每個座標上的數都是0。現在,我們首先進行 n 次操作,每次操作將某一位置x上的數加c。近下來,進行 m 次詢問,每個詢問包含兩個整數l和r,你需要求出在區間 l,r 之間的所有數的和。輸入格式 第一行包含兩個整數n和m。接下來 n 行,每行包含兩個整數x和c。再接下裡 ...