1. 程式人生 > >hdu5316區間最值問題(附帶題目意思詳解) 一次ac

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讀取到的當前幀的矩陣 # 返回的是元組型別,所以

深度學習 --- 卷積神經網路CNNLeNet-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=