P2839 [国家集训队]middle
生活随笔
收集整理的這篇文章主要介紹了
P2839 [国家集训队]middle
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題面
? 提一下靜態(tài)區(qū)間第k小的nlog2n的做法:
1. 建關(guān)于排名的主席樹(按排名順序建樹)。
2. 二分答案。
? 這樣做靜態(tài)區(qū)間第k小的雖然有些ZZ,但它的意義在于將線段樹
? 維護的對象改變了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,cnt; 4 int a[5],midd; 5 int val[20050]; 6 int pos[20050]; 7 int root[20050]; 8 int son[500050][2]; 9 struct node 10 { 11 int sum,l,r; 12 void clear() 13 { 14 sum=0; 15 l=r=0; 16 } 17 }w[500050],ans; 18 node merge(node a,node b) 19 { 20 node tmp; 21 tmp.sum=a.sum+b.sum; 22 tmp.l=max(a.l,a.sum+b.l); 23 tmp.r=max(b.r,b.sum+a.r); 24 return tmp; 25 } 26 bool cmp(int x,int y) 27 { 28 return val[x]<val[y]; 29 } 30 void build(int &u,int l,int r) 31 { 32 u=++cnt; 33 if(l==r) 34 { 35 w[u].sum=r-l+1; 36 w[u].l=w[u].r=r-l+1; 37 return ; 38 } 39 int mid=(l+r)>>1; 40 build(son[u][0],l,mid); 41 build(son[u][1],mid+1,r); 42 w[u]=merge(w[son[u][0]],w[son[u][1]]); 43 } 44 void calc(int &u,int v,int l,int r,int pos) 45 { 46 u=++cnt;w[u]=w[v]; 47 son[u][0]=son[v][0]; 48 son[u][1]=son[v][1]; 49 if(l==r) 50 { 51 w[u].sum=-1; 52 w[u].l=w[u].r=-1; 53 return ; 54 } 55 int mid=(l+r)>>1; 56 if(pos<=mid) calc(son[u][0],son[v][0],l,mid,pos); 57 else calc(son[u][1],son[v][1],mid+1,r,pos); 58 w[u]=merge(w[son[u][0]],w[son[u][1]]); 59 } 60 void ask(int u,int l,int r,int L,int R) 61 { 62 if(L<=l&&r<=R) 63 { 64 ans=merge(ans,w[u]); 65 return ; 66 } 67 int mid=(l+r)>>1; 68 if(L<=mid) ask(son[u][0],l,mid,L,R); 69 if(R>mid) ask(son[u][1],mid+1,r,L,R); 70 } 71 bool check(int u) 72 { 73 int sum=0; 74 if(a[2]+1<=a[3]) 75 { 76 ans.clear(); 77 ask(root[u],1,n,a[2]+1,a[3]); 78 sum+=ans.sum; 79 } 80 if(a[1]<=a[2]) 81 { 82 ans.clear(); 83 ask(root[u],1,n,a[1],a[2]); 84 sum+=ans.r; 85 } 86 if(a[3]+1<=a[4]) 87 { 88 ans.clear(); 89 ask(root[u],1,n,a[3]+1,a[4]); 90 sum+=ans.l; 91 } 92 return sum>=0; 93 } 94 int main() 95 { 96 scanf("%d",&n); 97 for(int i=1;i<=n;++i) 98 { 99 scanf("%d",&val[i]); 100 pos[i]=i; 101 } 102 sort(pos+1,pos+n+1,cmp); 103 build(root[0],1,n); 104 for(int i=1;i<=n;++i) 105 calc(root[i],root[i-1],1,n,pos[i]); 106 scanf("%d",&m); 107 while(m--) 108 { 109 for(int i=1;i<=4;++i) 110 { 111 scanf("%d",&a[i]); 112 a[i]=(a[i]+midd)%n+1; 113 } 114 sort(a+1,a+5); 115 int l=1,r=n; 116 while(l<r) 117 { 118 int mid=(l+r+1)>>1; 119 if(check(mid)) l=mid; 120 else r=mid-1; 121 } 122 midd=val[pos[l+1]]; 123 printf("%d\n",midd); 124 } 125 return 0; 126 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/wyher/p/10376280.html
總結(jié)
以上是生活随笔為你收集整理的P2839 [国家集训队]middle的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Neo4j--第一章
- 下一篇: P3225 [HNOI2012]矿场搭建