1. 程式人生 > >HDU6406(ST表)

HDU6406(ST表)

題意

給一個長度為n的序列,從i = 1開始貪心的取當前最大的值,記長度len為最大值改變多少次。

有m次詢問,每次改變序列中的某個值,問改變後len的長度。(n = 1,len = 1)

樣例

1
5 3
1 2 3 4 4
1 5
5 5
2 3

題解

分前半段和後半段考慮,對於每個位置,dp[0][i]表示從第一個元素到第i個元素的步數,dp[1][i]表示從i貪心的往後走的步數。

這樣的話用ST表維護區間最大值和它的下表,當改變某一位的值,那就是這一位前的最大值下表j的dp[0][j],和這一位後的第一個大於它值下表k的dp[1][k]。ans = dp[0][j] + dp[1][k]。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <vector>
#include <string.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
int N, a[maxn];
int f[maxn][20],dp[2][maxn];

void init()
{
    for(int i = 1; i <= N; i++) f[i][0] = i;
    for(int k = 1; (1<<k) <= N; k++)
    {
        for(int i = 1; i+(1<<k)-1 <= N; i++)
        {
            if(a[f[i][k-1]] >= a[f[i+(1<<(k-1))][k-1]]) f[i][k] = f[i][k-1];
            else f[i][k] = f[i+(1<<(k-1))][k-1];
        }
    }
}

int query(int L, int R)
{
    if(R<L) return 0;
    int k = 0;
    while( (1<<(k+1))-1 <= R-L ) k++;
    if( a[f[L][k]] >= a[f[R-(1<<k)+1][k]] ) return f[L][k];
    else return f[R-(1<<k)+1][k];
}
int main()
{
    int T, n, m, i, p ,q;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &m);
        for(i = 1; i <= n; i++) scanf("%d", &a[i]);
        N = n;
        init();
        dp[0][1] =1;
        int Max = 1;
        for(i = 2; i <= n; i++)
        {
            if(a[i] > a[Max]) {
                dp[0][i] = dp[0][Max]+1;
                Max = i;
            }
            else dp[0][i] = -1;
        }

        dp[1][n] = 1;
        for(i = n-1; i >= 1; i--)
        {
            int l = i+1, r = n;
            while(l < r)
            {
                int mid = (l+r)>>1;
                if(a[query(l,mid)]>a[i]) r = mid;
                else l = mid+1;
            }
            dp[1][i] = a[r]>a[i] ? dp[1][l]+1 : 1;
        }
        while(m--)
        {
            scanf("%d%d", &p, &q);
            int pos = query(1, p-1);
            int xx = a[pos];
            int ans = dp[0][pos];
            if(q > a[pos]) xx = q, ans++; ///xx取改變值和原值中較大一個
            int l = p+1, r = n;
            while(l < r)  ///二分找到後面大於xx的值
            {
                int mid = l+(r-l)/2;
                if(a[query(p+1,mid)]>xx) r = mid;
                else l = mid+1;
            }
            if(a[l]>xx) ans += dp[1][l];
            printf("%d\n", ans);
        }
    }
    return 0;
}

相關推薦

HDU6406ST

題意 給一個長度為n的序列,從i = 1開始貪心的取當前最大的值,記長度len為最大值改變多少次。 有m次詢問,每次改變序列中的某個值,問改變後len的長度。(n = 1,len = 1) 樣例 1 5 3 1 2 3 4 4 1 5 5 5 2 3 題解

The Water Problem HDU - 5443 ST

題目 https://cn.vjudge.net/problem/HDU-5443 題意 給你n個數 q次查詢 ,每次輸入區間最大值 思路 裸地ST表或線段樹 #include <bits/stdc++.h> using namespace std; int

A Magic Lamp HDU - 3183 ST

Kiki likes traveling. One day she finds a magic lamp, unfortunately the genie in the lamp is not so kind. Kiki must answer a question, and then the

RMQST

linu math getchar() pre stream clas void inline ret #include<iostream> #include<cstdio> #include<cmath> using namespac

UVA 12338:Anti-Rhyme Pairs後綴數組+ST

後綴數組 min -1 class break nbsp con mem span 【題目鏈接】 click 【題目大意】   給出一些字符串,詢問查詢任意兩個字符串的最長公共前綴 【題解】   將字符串拼接,對拼接的字符串做後綴數組,對於查詢的兩

bzoj4569: [Scoi2016]萌萌噠ST+並查集

bool pri play har name pre hide ide closed   好喵喵的題   將一個要求用ST表分割成logn個要求,如果把f[i][j]和f[u][v]在同一個集合,那麽f[i][j-1]和f[u][v-1],f[i+2^(j-1)][j-1

ZSTU 4241 聖杯戰爭ST+二分

esp 戰爭 def 最大值 cal continue online 問題 %d 題目鏈接 ZSTU 4241 問題轉化為有很多區間,現在每次給定一個區間求這個區間和之前所有區間中的某一個的交集的最大長度。 強制在線。 首先我們把所有的區間預處理出來。 然後去重(

【題解】 bzoj3956: Count ST+單調棧

n) uri 方案 自己 ace 貢獻 int n+1 思路 題面 Solution 看了一點點題解,自己又剛了\(2h30min\),剛了出來qwq,我好菜啊qwq 貌似這道題是BZOJ 4826的弱化,弱化都不會qwq涼涼 Solution 首先你可以考慮,找出\([

Luogu P2880 [USACO07JAN]平衡的陣容Balanced Lineup ST模板

傳送門(ST表裸題) ST表是一種很優雅的演算法,用於求靜態RMQ 陣列l[i][j]表示從i開始,長度為2^j的序列中的最大值 注意事項: 1.核心部分: for(int j = 1; (1<<j) <= n; j++) for(int i = 1;

codeforces 713 D二維st

題目連結 題解 題意:給你一個01矩陣,詢問一個矩形區域內最大的全1正方形。 考慮到硬做很麻煩,所以先二分出一個值就可以了。 st表時間複雜度:n^2*log^2  程式碼: #include <cstdio> #include <iostr

bzoj5308[Zjoi2018]胖線段樹,二分,st

Description Cedyks是九條可憐的好朋友(可能這場比賽公開以後就不是了),也是這題的主人公。 Cedyks是一個富有的男孩子。他住在著名的ThePLace(宮殿)中。 Cedyks是一個努力的男孩子。他每天都做著不一樣的題來鍛鍊他的The SaLt(靈魂)。 這天,他打

GCD ST,二分求區間查詢

HUD 5726 GCD 給一個序列,多次查詢區間的最大公約數,並求出同樣是這個最大公約數的區間有多少個。 區間查詢採用ST表,第二問查詢利用區間向右延伸最大公約數遞減的規律可通過二分快速找到右邊界。把第一問的答案先求出來,表示要查詢的公約數加入map。 然後列舉左端點二

bzoj千題計劃312:bzoj2119: 股市的預測字尾陣列+st

#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #d

【洛谷 P2216】 [HAOI2007]理想的正方形二維ST

memset == string using 二維 size 做出 ++ read 題目鏈接 做出二維\(ST\)表,然後\(O(n^2)\)掃一遍就好了。 #include <cstdio> #include <cstring> #include

poj3246st模板

思路:st表模板題,當然線段樹什麼的也可以。。。 #include <cstdio> #include <cstdlib> #include <cstring>

POJ 3693 Maximum repetition substring後綴數組+ST

%s 是否 很難 span 順序 template else if lse turn 題意 定義一個字符串的復讀數為它可以被分割成最多的的若幹個相同連續的子串個數,求一個字符串中復讀次數最大的子串位置,若有相同,輸出字典序最小的。 \(1 \leq \text{length

Symbol Table符號

-- 預測 smallest 是否 性能分析 .cn 變量 不能 級別 一、定義 符號表是一種存儲鍵值對的數據結構並且支持兩種操作:將新的鍵值對插入符號表中(insert);根據給定的鍵值查找對應的值(search)。 二、API 1、無序符號表 幾個設計決策: A、

深入淺出數據結構C語言版9——多重廣義

不同 滿足 大學 logs 維數 我會 明顯 http 多維   在深入淺出數據結構系列前面的文章中,我們一直在討論的表其實是“線性表”,其形式如下:   由a1,a2,a3,……a(n-1)個元素組成的序列,其中每一個元素ai(0<i<n)都是一個“原子”,“

橫掃芯片後,紫光欲進軍公有雲 數百億資金已到位大事

新的 一家子 模式 信息 資金 通過 展訊 發布 所有 紫光集團有可能通過收購具有先進雲計算技術的公司以快速切入公有雲市場,這是其打造“芯-雲-網-端”信息產業生態鏈的重要一環。 繼投入數千億資金布局芯片制造產業之後,紫光集團又一個核心戰略浮

HDU 6215 Brute Force Sorting

show 滿足 .cn namespace freopen vector 題意 判斷 type http://acm.hdu.edu.cn/showproblem.php?pid=6215 題意:給出一個序列,對於每個數,它必須大於等於它前一個數,小於等於後一個數,如果不