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。再接下裡 ...