日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2017西安交大ACM小学期数据结构 [树状数组,极大值]

發布時間:2023/12/3 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2017西安交大ACM小学期数据结构 [树状数组,极大值] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Problem D

發布時間: 2017年6月28日 10:51?? 最后更新: 2017年6月28日 16:38?? 時間限制: 1000ms?? 內存限制: 32M

描述

給定一個長度為n的序列a1,?a2, ...,?an

k滿足2kn?1,?ak>ak?1ak>ak+1時,?將元素k稱為極大值點,

給出q個操作, 操作分為兩種

對于形如1?x?y的操作, 將ax修改為y, 滿足1xn,?1y109

對于形如2?x?y的操作, 輸出區間[x,y]內有多少個"極大值點", 滿足1xyn

9×104n105,?9×104q105,?1ai109

輸入

第一行兩個整數n,?q, 意義如上所述。
第二行n個整數, 表示序列a
接下來q行, 每行第一個數為opt, 之后緊跟兩個數, 意義如上所述。

輸出

對于每個操作2, 輸出答案, 一行一個。

樣例輸入1?復制 8 3 3 1 4 1 5 9 2 6 2 1 8 1 3 1 2 1 8 樣例輸出1 2 1 我們可以直接創建一個樹狀數組,如果某個元素x是極大值,那么我們就往蜀樹狀數組相應的位置寫上1,這樣的話,想要統計區間最大值的個數,只需要

統計樹狀數組的區間和就可以了。

而在維護的時候(修改a[x] 為y)要小心的考慮

這里舉一個例子,要將a[x]改為y的情況

(1)如果修改前a[x]是極大值,修改后a[x]非極大值,那么add(x,-1)

(2)如果修改前a[x]非極大值,修改后a[x]為極大值,那add(x,-1)

(3).。。注意a[x]改成y不光影響x出的值,x-1,x+1處都有可能被影響

。。。要注意

代碼:

#include <iostream> #include <cstdio> using namespace std; const int MAX = 1e5+7; int n,q; int a[MAX]; int b[MAX]; inline int lowbit(int x){return x & (-x); } int getsum(int pos){int res = 0;while(pos){res += b[pos];pos -= lowbit(pos);}return res; } void add(int pos,int val){while(pos <= n){b[pos] += val;pos += lowbit(pos);} } inline bool check(int pos){return a[pos] > a[pos+1] && a[pos] > a[pos-1]; }int main(){scanf("%d%d",&n,&q);for(int i = 1;i <= n;i++){scanf("%d",&a[i]);}for(int i = 2;i < n;i++){if(check(i)){add(i,1);}}while(q--){int opt;scanf("%d",&opt);if(opt == 1){int x,y;scanf("%d%d",&x,&y);if(x == 1){if(!check(2) && (a[2] > y && a[2] > a[3])){add(2,1);}if(check(2) && !(a[2] > y && a[2] > a[3])){add(2,-1);}}else if(x == n){if(!check(n-1) && (a[n-1] > a[n-2] && a[n-1] > y)){add(n-1,1);}if(check(n-1) && !(a[n-1] > a[n-2] && a[n-1] > y)){add(n-1,-1);}}else{if(!check(x) && (y > a[x-1] && y > a[x+1]) ){add(x,1);}if(check(x) && !(y > a[x-1] && y > a[x+1]) ){add(x,-1);}if(x >= 3 && !check(x-1) && (a[x-1] > a[x-2] && a[x-1] > y)){add(x-1,1);}if(x >= 3 && check(x-1) && !(a[x-1] > a[x-2] && a[x-1] > y)){add(x-1,-1);}if(x <= n-2 && !check(x+1) && (a[x+1] > a[x+2] && a[x+1] > y)){add(x+1,1);}if(x <= n-2 && check(x+1) && !(a[x+1] > a[x+2] && a[x+1] > y)){add(x+1,-1);}}a[x] = y;}else{int x,y ;scanf("%d%d",&x,&y);printf("%d\n",getsum(y) - getsum(x-1));}}return 0; }




總結

以上是生活随笔為你收集整理的2017西安交大ACM小学期数据结构 [树状数组,极大值]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。