hdu 4638 Group 樹狀陣列

2022-05-06 11:42:12 字數 1618 閱讀 1991

題意

找到區間裡有多少組連續數字串

分析:**)

思路:顯然,我們要使得value最大,就要盡量將連續的id分在一組,所以問題轉化為求乙個區間中連續id區間的個數。我們從左往右掃瞄,依次考慮右端點為i的詢問,設dp[l]為區間[l,i]的連續區間個數,po[i]為i出現的位置,若還未出現,則為0,設我們當前考慮的右端點為a[i],首先我們假設a[i]不能和區間[1,i-1]中的任何乙個數分到一組,則我們要將dp[1]到dp[i-1]全部加1,然後考慮po[a[i]+1]是否不為0,若不為0則說明a[i]-1已經在前面出現,則我們需要將dp[1]到dp[po[a[i]+1]]全部減乙個1,因為a[i]可以和a[i]+1分為一組,則我們之前加的1是多餘的。對於a[i]-1的情況同理。以上操作可以由線段樹或者樹狀陣列什麼的實現,然後再將詢問按照右端點從小到大排序,離線處理即可,以下是**實現

//

file name: 1007.cpp

//author: zlbing

//created time: 2023年08月02日 星期五 07時44分46秒

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define cl(x,v); memset(x,v,sizeof(x));

#define inf 0x3f3f3f3f

#define ll long long

#define rep(i,r,n) for(int i=r;i<=n;i++)

#define rrep(i,n,r) for(int i=n;i>=r;i--)

const

int maxn=1e5+100

;int

tree[maxn];

intn;

int lowbit(intx)

void add(int pos,int val)///

/如果要把a[i]增加v,可以通過呼叫如下函式實現 }

int read(int x)//

前x項和

return

s; }

inta[maxn],pos[maxn];

struct

node

};vector

q;int

ans[maxn];

intmain()

q.clear();

node tmp;

rep(i,

1,m)

sort(q.begin(),q.end());

cl(tree,0);

int j=0

;

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

if(a[i]-1>=1&&pos[a[i]-1]while(q[j].r==i)

}rep(i,

1,m)

}return0;

}

hdu4638 Group(樹狀陣列)

題目大意 給乙個1 n的排列,然後詢問 x,y 區間中有多少個連續的段。如給乙個3 1 2 5 4,查詢是2 4,那麼就是問1 2 5中有多少個連續的串,一共有兩個串,1 2為乙個串,5為乙個串 若查詢是2 5,則問的是1 2 5 4中有多少個連續的串,一共有兩個串,1 2為乙個串,4 5 為乙個串...

HDU 4638 Group 樹狀陣列

詢問一段區間裡的數能組成多少段連續的數。先考慮從左往右乙個數乙個數新增,考慮當前新增了i 1個數的答案是x,那麼可以看出新增完i個數後的答案是根據a i 1和a i 1是否已經新增而定的 如果a i 1或者a i 1已經新增乙個,則段數不變,如果都沒新增則段數加1,如果都新增了則段數減1。設v i ...

Hdu 4638 Group 離線 樹狀陣列

題目大意 給你1 n的任意全排列,詢問q次,每次詢問區間 l r 內的組數,組數的定義為 在乙個連續區間中,可以把區間中的數任意分成幾組,每組的所有數必須連續,比如 7 5 8的組數為2,即7,8和5。解題思路 先假設每個數都是一組,然後查詢和他相鄰的兩個數是否在此之前出現過,如果出現則 出現的位置...