題意
找到區間裡有多少組連續數字串
分析:**)
思路:顯然,我們要使得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。解題思路 先假設每個數都是一組,然後查詢和他相鄰的兩個數是否在此之前出現過,如果出現則 出現的位置...