CDOJ 1157 數列 seq 分塊

2021-07-23 13:16:02 字數 1444 閱讀 3537

題意:給出乙個數列,兩種操作

1.修改操作:把數列中第i個數改為x

2.詢問操作:給定乙個位置i,問數列中有多少個位置j ( j>i ),滿足位置i與位置j間所有的數都不超過ai與aj的較大值。

簡單來說,操作2分為兩部分

1.位置i右邊相鄰連續的比它小的數字個數

2.位置i右邊不減序列長度

直接將數列分塊,分塊暴力維護和求解答案

第一部分詢問做法:記錄塊中最大值為多少,如果整個塊中值小於當前值,則答案直接加上乙個block,一直到找到第乙個大於a[

i]的值

第二部分詢問做法:將每個塊中的上公升序列都用vector儲存下來,使用時二分查詢答案

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#pragma comment(linker, "/stack:1024000000,1024000000");

using

namespace

std;

#define inf 0x3f3f3f3f

#define maxn 500005

int n,m;

int a[maxn];

int block,num,belong[maxn],l[maxn],r[maxn],mx[maxn];

vector

que[maxn];

void nex_init()

}void init()

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

r[num]=n;

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

}mx[i]=mx;

}}void update(int x,int val)

}mx[belong[x]]=mx;

}int part_a(int x)

if(pos>n) return sum;

pos=belong[x]+1;

while(pos<=num&&mx[pos]<=a[x])

if(pos>num) return sum;

pos=l[pos];

while(pos<=n&&a[pos]<=a[x])

return sum;

}int part_b(int x)

for(int i=belong[x]+1; i<=num; i++)

return ans;

}int query(int x)

int main()

else

}nex_init();

}return

0;}

DOTCPP 有關1157心得

思路易錯點 古希臘數學家畢達哥拉斯在自然數研究中發現,220的所有真約數 即不是自身的約數 之和為 1 2 4 5 10 11 20 22 44 55 110 284。而284的所有真約數為1 2 4 71 142,加起來恰好為220。人們對這樣的數感到很驚奇,並稱之為親和數。一般地講,如果兩個數中...

CDOJ 點球大戰 penalty

演算法 模擬 考點 字串的處理 首先是要讀入一整行可以使用getline cin,str 然後還要注意到 每組資料第一行為n 整數 cin n後若getline 會讀入換行符 所以在cin n 後需要先cin.get 然後再 getline cin,str 然後注意到此題只能從後判斷倒數的兩個單詞像...

題目1157 中位數

題目描述 中位數定義 一組資料按從小到大的順序依次排列,處在中間位置的乙個數 或最中間兩個資料的平均數 給出一組無序整數,求出中位數,如果求最中間兩個數的平均數,向下取整即可 不需要使用浮點數 輸入 該程式包含多組測試資料,每一組測試資料的第一行為n,代表該組測試資料報含的資料個數,1 n 1000...