智推推到這個題
發現標籤中竟然有線段樹。。?
因而貿然來了一發線段樹
衆所周知,線段樹的查詢是log(n)的
題目中"請注意最大數據時限只有0.8s,數據強度不低,請務必保證你的每次查詢複雜度爲 O(1)"
而後草草打完代碼居然AC了。。exm??
最慢也不過400msnode
好吧,很少說上代碼
首先是數據存貯,分別是左子節點,右子節點,maxx存貯當前節點的最大值c++
struct node{ int left,right,maxx; }tree[100000*4+10];
建樹,和常規同樣大數據
void build(int index,int l,int r) { tree[index].left=l,tree[index].right=r; if(l==r) { int x=read(); tree[index].maxx=x; return ; } int mid=(l+r)>>1; build(index<<1,l,mid),build(index<<1|1,mid+1,r); tree[index].maxx=max(tree[index<<1].maxx,tree[index<<1|1].maxx); }
區間查詢,記錄每一個和目標區間有交集的區間的最大值ui
int intervalask(int index,int l,int r) { if(tree[index].left>=l&&tree[index].right<=r) return tree[index].maxx; int tempmax=-0x7fffffff; if(tree[index<<1].right>=l) tempmax=max(intervalask(index<<1,l,r),tempmax); if(tree[index<<1|1].left<=r) tempmax=max(intervalask(index<<1|1,l,r),tempmax); return tempmax; }
AC代碼spa
#include<bits/stdc++.h> using namespace std; int n,m,ans; struct node{ int left,right,maxx; }tree[100000*4+10]; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-f; ch=getchar(); } while(ch<='9'&&ch>='0') { x=x*10+ch-'0'; ch=getchar(); } return f*x; } void build(int index,int l,int r) { tree[index].left=l,tree[index].right=r; if(l==r) { int x=read(); tree[index].maxx=x; return ; } int mid=(l+r)>>1; build(index<<1,l,mid),build(index<<1|1,mid+1,r); tree[index].maxx=max(tree[index<<1].maxx,tree[index<<1|1].maxx); } int intervalask(int index,int l,int r) { if(tree[index].left>=l&&tree[index].right<=r) return tree[index].maxx; int tempmax=-0x7fffffff; if(tree[index<<1].right>=l) tempmax=max(intervalask(index<<1,l,r),tempmax); if(tree[index<<1|1].left<=r) tempmax=max(intervalask(index<<1|1,l,r),tempmax); return tempmax; } int main() { n=read(),m=read(); build(1,1,n); for(register int i=1,l,r;i<=m;i++) { l=read(),r=read(); printf("%d\n",intervalask(1,l,r)); } }
就這麼多,學學半,若是有不理解的地方能夠私信code