給定乙個序列a[i],每次詢問l,r,求[l,r]內最長子串,使得該子串為不上公升子串或不下降子串
第一行n,表示a陣列有多少元素
接下來一行為n個整數a[i]
接下來乙個整數q,表示詢問數量
接下來q行,每行2個整數l,r
對於每個詢問,求[l,r]內最長子串,使得該子串為不上公升子串或不下降子串
91 2 3 4 5 6 5 4 3
51 6
1 72 7
1 95 966
564樣例解釋
五個詢問分別對應
[1,6][1,6][2,6][1,6][6,9]
n,q<=50000
by 乙個讀錯題的沙茶
好像寫個線段樹就可以維護區間資訊了???
我寫了個線段樹分治啊啊啊。。。
首先對於詢問在區間上打上標記,如果到了葉結點就可以停下來用整個區間的答案來更新。
每次考慮跨過中點的線段,字首字尾掃一下就好了。
#include#include#include#include#include#define rep(i,s,t) for(int i=s;i<=t;i++)#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int buffersize=1<<16;
char buffer[buffersize],*head,*tail;
inline char getchar()
return *head++;
}inline int read()
const int maxn=50010;
const int maxnode=6000010;
struct query q[maxnode];
int n,cnt,ans[maxn],f[maxn],g[maxn],a[maxn],first[maxn*4],res[maxn*4];
void addquery(int o,int ql,int qr,int id) ;first[o]=cnt;
}void solve(int o,int l,int r)
else
solve(lc,l,mid);solve(rc,mid+1,r);
res[o]=max(res[lc],res[rc]);
int ok;
ok=1;f[mid+1]=1;
rep(i,mid+2,r)
res[o]=max(res[o],f[l]+f[r]);
ok=1;g[mid+1]=1;
rep(i,mid+2,r)
ok=1;if(a[mid]>a[mid+1]) ok=0;g[mid]=ok;
dwn(i,mid-1,l) }}
int main()
solve(1,1,n);
rep(i,1,m) printf("%d\n",ans[i]);
return 0;
}
BZOJ 4491 我也不知道題目名字是什麼
給定乙個序列a i 每次詢問l,r,求 l,r 內最長子串,使得該子串為不上公升子串或不下降子串 第一行n,表示a陣列有多少元素 接下來一行為n個整數a i 接下來乙個整數q,表示詢問數量 接下來q行,每行2個整數l,r 對於每個詢問,求 l,r 內最長子串,使得該子串為不上公升子串或不下降子串 9...
BZOJ 4491 我也不知道題目名字是什麼
time limit 10 sec memory limit 512 mb submit 278 solved 154 submit status discuss 給定乙個序列a i 每次詢問l,r,求 l,r 內最長子串,使得該子串為不上公升子串或不下降子串 第一行n,表示a陣列有多少元素 接下來...
BZOJ4491 我也不知道題目名字是什麼
試題描述 給定乙個序列 a i 每次詢問 l,r 求 l,r 內最長子串,使得該子串為不上公升子串或不下降子串 輸入第一行 n 表示 a 陣列有多少元素 接下來一行為 n 個整數 a i 接下來乙個整數 q 表示詢問數量 接下來 q 行,每行 2 個整數 l r 輸出對於每個詢問,求 l,r 內最長...