hdu5316區間最值問題(附帶題目意思詳解) 一次ac
T組資料
N個數字,M次操作
op=0:找出L-R區間內的最大‘值’
op=1:把a位置的數字換成b
對最大‘值’的定義:取區間內的最大子序列,需要保證子序列的下標為奇偶交替的
用線段樹分別記錄每個區間的
.........s1.......奇數位開始,奇數位結束
.........s2.......奇數位開始,偶數為結束
.........s3.......偶數位開始,偶數位結束
.........s4.......偶數位開始,奇數位結束
對每次詢問分別處理4種情況的最大值即可
此題乍一看比較麻煩, 筆者剛開始想到dp,但沒有思路,而此題又有很裸地線段樹特點,於是用線段樹做。此題與一般線段樹不同的是,節點上記錄的是幾個值
#include<iostream> #include<stdio.h> #include<math.h> #include<cstring> using namespace std; typedef long long ll; const int N=100010; const ll INF=-1e9; int n,m; ll t,a[N]; typedef struct { int left,right; //.........s1.......奇數位開始,奇數位結束 //.........s2.......奇數位開始,偶數為結束 //.........s3.......偶數位開始,偶數位結束 //.........s4.......偶數位開始,奇數位結束 ll s1,s2,s3,s4; }P; P per[4*N]; typedef struct { ll s1,s2,s3,s4; }data; ll MAX(ll a,int b) { if(a>b) return a; return b; } ll MAX(ll a,ll b,ll c,ll d) { ll m1=max(a,b),m2=max(c,d); return max(m1,m2); } void build(int id,ll left,ll right) { per[id].left=left; per[id].right=right; if(left==right) { if(left&1) { per[id].s1=a[left]; per[id].s2=INF; per[id].s3=INF; per[id].s4=INF; } else { per[id].s1=INF; per[id].s2=INF; per[id].s3=a[left]; per[id].s4=INF; } return; } else { int mid=(left+right)>>1,len1=id<<1,len2=id<<1|1; build(len1,left,mid); build(len2,mid+1,right); ll as1,as2,as3,as4,bs1,bs2,bs3,bs4; as1=per[len1].s1; as2=per[len1].s2; as3=per[len1].s3; as4=per[len1].s4; bs1=per[len2].s1; bs2=per[len2].s2; bs3=per[len2].s3; bs4=per[len2].s4; per[id].s1=MAX(as1,bs1,as1+bs4,as2+bs1); per[id].s2=MAX(as2,bs2,as2+bs2,as1+bs3); per[id].s3=MAX(as3,bs3,as3+bs2,as4+bs3); per[id].s4=MAX(as4,bs4,as4+bs4,as3+bs1); } } void update(int id,ll a,ll b) {//cout<<"a= "<<a<<" b= "<<b<<endl; if(per[id].left>a||per[id].right<a) return; if(per[id].left==per[id].right&&per[id].left==a) {//cout<<"updata= "<<a<<" b= "<<b<<endl; if(a&1) per[id].s1=b; else per[id].s3=b; } else { ll mid=(per[id].left+per[id].right)>>1; ll len1=id<<1,len2=len1+1; if(mid<a) update(len2,a,b); else if(mid>=a) update(len1,a,b); ll as1,as2,as3,as4,bs1,bs2,bs3,bs4; as1=per[len1].s1; as2=per[len1].s2; as3=per[len1].s3; as4=per[len1].s4; bs1=per[len2].s1; bs2=per[len2].s2; bs3=per[len2].s3; bs4=per[len2].s4; per[id].s1=MAX(as1,bs1,as1+bs4,as2+bs1); per[id].s2=MAX(as2,bs2,as2+bs2,as1+bs3); per[id].s3=MAX(as3,bs3,as3+bs2,as4+bs3); per[id].s4=MAX(as4,bs4,as4+bs4,as3+bs1); } } data query(int id,ll l,ll r) { ll s; if(per[id].left==l&&per[id].right==r) { data da; da.s1=per[id].s1; da.s2=per[id].s2; da.s3=per[id].s3; da.s4=per[id].s4; return da; } if(per[id].left>r||per[id].right<l) { data da; da.s1=INF; da.s2=INF; da.s3=INF; da.s4=INF; return da; } ll mid=(per[id].left+per[id].right)>>1; ll len1=id<<1,len2=len1+1; if(r<=mid) return query(len1,l,r); else if(l>mid) return query(len2,l,r); else { data d1=query(len1,l,mid); data d2=query(len2,mid+1,r); data d3; d3.s1=MAX(d1.s1,d2.s1,d1.s1+d2.s4,d1.s2+d2.s1); d3.s2=MAX(d1.s2,d2.s2,d1.s1+d2.s3,d1.s2+d2.s2); d3.s3=MAX(d1.s3,d2.s3,d1.s3+d2.s2,d1.s4+d2.s3); d3.s4=MAX(d1.s4,d2.s4,d1.s3+d2.s1,d1.s4+d2.s4); return d3; } } int main() { int i,j; ll l,r,k; while(~scanf("%d",&t)) { while(t--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,1,n); for(i=0;i<m;i++) { cin>>k>>l>>r; if(k==0) { data da=query(1,l,r); ll mmax=MAX(da.s1,da.s2,da.s3,da.s4); cout<<mmax<<endl; } if(k==1) { update(1,l,r); //for(i=1;i<=4*n;i++) } } } } return 0; }
相關推薦
hdu5316區間最值問題(附帶題目意思詳解) 一次ac
T組資料 N個數字,M次操作 op=0:找出L-R區間內的最大‘值’ op=1:把a位置的數字換成b 對最大‘值’的定義:取區間內的最大子序列,需要保證子序列的下標為奇偶交替的 用線段樹分別記錄每個區間的 .........s1.......奇數位開始,奇數
Subspace Clustering詳解(附帶CLIQUE演算法詳解)
Subspace Clustering詳解 第二十四次寫部落格,本人數學基礎不是太好,如果有幸能得到讀者指正,感激不盡,希望能借此機會向大家學習。這一篇作為密度聚類演算法族的第三篇,主要是介紹一種用來發現子空間中的簇的演算法——Subspace Cluster
線段樹基礎:單點更新,區間最值(和)查詢
單點更新,區間查詢 線段樹可以解決一類區間問題,例如最基礎的單點更新,區間最值查詢。 程式碼如下: #include<bits/stdc++.h> using namespace std; const int maxn = 10000; //原
微享商盟消費返利小程序系統開發( 程序制作詳解)
服務 系統 app 小程序 代碼 源碼 好用的同時總是少不了一些坑,或許我是才接觸沒多久的緣故吧! 1.resttemplate fastjson替換jackson fastjson是國人的驕傲,符合國人的使用習慣。 微享商盟消費返利小程序系統
LINUX6——DNS域名解析服務搭建(正向解析新手詳解)
訪問 端口 模式 兩個 搭建 保存 color dom mail LINUX6——DNS域名解析服務搭建(正向解析新手詳解) -------------------------------概述------------------------------ DNS TC
吳恩達機器學習課程筆記02——處理房價預測問題(梯度下降演算法詳解)
建議記住的實用符號 符號 含義 m 樣本數目 x 輸入變數 y 輸出變數/目標變數
js實現快速排序,二分查詢 (詳解,一次學會)
js中幾大演算法,最近看到網上各路大神的解答,都蠻好的,自己也來玩一玩 一,快速排序 大致分三步: 在資料集之中,選擇一個元素作為"基準"(pivot)。 所有小於"基準"的元素,都移到"基準"的左邊;所有大於"基準"的元素,都移到"基準"的右邊。 對"基準"左邊和右邊的兩個子集,不斷重複
八皇後問題(遞歸方法詳解)
span isp als using ostream 開始 int 對角線 沒有 八皇後遞歸詳解 核心代碼如下: //八皇後遞歸解法 #include<iostream> using namespace std; int queen[9] = {-1,-1
Nginx 性能優化(配置文件詳解)
pro linux cti size 長時間 並發連接 poll ipv4 服務器端 隨著訪問量的不斷增加,需要對 Nginx 和內核做相應的優化來滿足高並發用戶的訪問,那下面在單臺 Nginx 服務器來優化相關參數。 Nginx.conf 配置優化: worker_
opencv-python 的Camshift函式(附逐行詳解)
這是我在OpenCV-python教程中找到的程式碼並附上的詳解 import cv2 import numpy as np cap = cv2.VideoCapture(0) # ret判斷是否讀到圖片 # frame讀取到的當前幀的矩陣 # 返回的是元組型別,所以
深度學習 --- 卷積神經網路CNN(LeNet-5網路詳解)
卷積神經網路(Convolutional Neural Network,CNN)是一種前饋型的神經網路,其在大型影象處理方面有出色的表現,目前已經被大範圍使用到影象分類、定位等領域中。相比於其他神經網路結構,卷積神經網路需要的引數相對較少,使的其能夠廣泛應用。 本節打算先介紹背景和簡單的基本
演算法提高快速冪(快速冪演算法詳解)
問題描述 給定A, B, P,求(A^B) mod P。 輸入格式 輸入共一行。 第一行有三個數,N, M, P。 輸出格式 輸出共一行,表示所求。 樣例輸入 2 5 3 樣例輸出 2 資料規模和約定 共10組資料 對100%的資料,A, B為lon
Python3爬蟲學習筆記(1.urllib庫詳解)
1.什麼是爬蟲:略,到處都有講解。 雖然是入門,不過沒有Python基礎的同學看起來可能費勁,建議稍學下Python 之前學習前端知識也是為了能看懂HTML,便於爬蟲學習,建議瞭解下前端知識 2.re
K-th Number POJ - 2104 (主席樹 學習詳解)
https://cn.vjudge.net/problem/POJ-2104 題意 給你N個數 嗎、M次查詢,每次查詢給你 IJK 問第I個數到第J個數中第K大 思路 字典樹,每新增一個數都建立一棵線段樹,J和I 做減法就可以的到這個區間的線段樹 #include <c
Java經典設計模式之十一種行為型模式(附例項和詳解)
Java經典設計模式共有21中,分為三大類:建立型模式(5種)、結構型模式(7種)和行為型模式(11種)。 行為型模式細分為如下11種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯
R語言與文字挖掘入門篇(各軟體包詳解)-謝佳標-專題視訊課程
R語言與文字挖掘入門篇(各軟體包詳解)—2926人已學習 課程介紹 本課程主要是利用R語言工具實現文字挖掘。主要內容包括:1、介紹文字挖掘的基本原理;2、文字挖掘相關包的安裝講解;3、tm包和Rwordseg包的詳解。課程收益 學習完本課程,學員能掌握利用
設計模式之五大建立型模式(附例項和詳解)
一、概況 總體來說設計模式分為三大類: (1)建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。 (2)結構型模式,共七種:介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。 (3)行為型
Python基礎學習資料(語法、函式詳解)
目錄 目錄 1 常用函式 5 input() 5 int() 6 len() 7 list() 與tuple相對 8 tuple() 與list相對 9 sum() 10 max() 11 min() 12 print() 13 range() 14 set() 15 sorted() 16
netty原始碼深入研究(從客戶端入手)第四篇(讀寫超時詳解)
怎麼設定讀寫超時的監聽函式呢,首先從文件開始,或者看看官方有沒有例子,一般任何平臺的官方都會或多或少的提供例子。 官方文件有這樣一個類new IdleStateHandler(readerIdleTimeSeconds, writerIdleTimeSeconds, all
Python3爬蟲學習筆記(4.BeautifulSoup庫詳解)
這是一個功能強大的庫,可以代替很多需要寫正則的地方 這是一個第三方解析庫,常規安裝方法: 調出cmd:pip install bs4 簡單瞭解: html = """ <html lang=