換個角度思考
阿新 • • 發佈:2018-11-18
esc roo div view names cst mat 函數 一個
即對於詢問 (l,r,x),你需要輸出 的值
其中 [exp] 是一個函數,它返回 1 當且僅當 exp 成立,其中 exp 表示某個表達式
換個角度思考
https://ac.nowcoder.com/acm/contest/275/E
題目描述
給定一個序列,有多次詢問,每次查詢區間裏小於等於某個數的元素的個數即對於詢問 (l,r,x),你需要輸出 的值
其中 [exp] 是一個函數,它返回 1 當且僅當 exp 成立,其中 exp 表示某個表達式
輸入描述:
第一行兩個整數n,mi
第二行n個整數表示序列a的元素,序列下標從1開始標號,保證1 ≤ a
≤ 105
5
之後有m行,每行三個整數(l,r,k),保證1 ≤ l ≤ r ≤ n,且1 ≤ k ≤ 10
輸出描述:
對於每一個詢問,輸出一個整數表示答案後回車示例1
輸入
5 1 1 2 3 4 5 1 5 3
輸出
3
備註:
數據範圍5
1 ≤ n ≤ 10
5
1 ≤ m ≤ 10
主席樹模板題
如果是向右子樹走的話,要加上左子樹的值
1 #include<iostream> 2 #include<cmath> 3 #include<cstring> 4 #include<set> 5 #include<map> 6 #include<queue> 7 #include<algorithm> 8 #include<vector> 9View Code#include<cstdio> 10 #define N 500005 11 using namespace std; 12 struct sair{ 13 int l,r,v; 14 }tree[N*40]; 15 int root[N],cnt; 16 17 void pushup(int rt){ 18 tree[rt].v=tree[tree[rt].l].v+tree[tree[rt].r].v; 19 } 20 21 void add(int pre,int cur,int pos,int l,int r){ 22 if(l==r){ 23 tree[cur].v=tree[pre].v+1; 24 return; 25 } 26 int mid=(l+r)/2; 27 if(pos<=mid){ 28 tree[cur].l=++cnt; 29 tree[cur].r=tree[pre].r; 30 add(tree[pre].l,tree[cur].l,pos,l,mid); 31 } 32 else{ 33 tree[cur].r=++cnt; 34 tree[cur].l=tree[pre].l; 35 add(tree[pre].r,tree[cur].r,pos,mid+1,r); 36 } 37 pushup(cur); 38 } 39 40 int query(int pre,int cur,int k,int l,int r){ 41 if(l==r){ 42 return tree[cur].v-tree[pre].v; 43 } 44 int mid=(l+r)/2; 45 int ans=0; 46 if(k<=mid) 47 ans+=query(tree[pre].l,tree[cur].l,k,l,mid); 48 else 49 ans+=tree[tree[cur].l].v-tree[tree[pre].l].v+query(tree[pre].r,tree[cur].r,k,mid+1,r); 50 return ans; 51 } 52 53 int main(){ 54 int n,m,x,y,k; 55 scanf("%d %d",&n,&m); 56 cnt=0; 57 for(int i=1;i<=n;i++){ 58 scanf("%d",&x); 59 root[i]=++cnt; 60 add(root[i-1],root[i],x,1,1e5+5); 61 } 62 while(m--){ 63 scanf("%d %d %d",&x,&y,&k); 64 printf("%d\n",query(root[x-1],root[y],k,1,1e5+5)); 65 } 66 }
換個角度思考