题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6315
In a galaxy far, far away, there are two integer sequence a and b of length n.
b is a static permutation of 1 to n. Initially a is filled with zeroes.
There are two kind of operations:
1. add l r: add one for al,al+1...aral,al+1...ar
2. query l r: query ∑ri=l⌊ai/bi⌋∑i=lr⌊ai/bi⌋
InputThere are multiple test cases, please read till the end of input file. b is a static permutation of 1 to n. Initially a is filled with zeroes.
There are two kind of operations:
1. add l r: add one for al,al+1...aral,al+1...ar
2. query l r: query ∑ri=l⌊ai/bi⌋∑i=lr⌊ai/bi⌋
For each test case, in the first line, two integers n,q, representing the length of a,b and the number of queries.
In the second line, n integers separated by spaces, representing permutation b.
In the following q lines, each line is either in the form 'add l r' or 'query l r', representing an operation.
1≤n,q≤1000001≤n,q≤100000, 1≤l≤r≤n1≤l≤r≤n, there're no more than 5 test cases.
OutputOutput the answer for each 'query', each one line.
Sample Input
5 12 1 5 2 4 3 add 1 4 query 1 4 add 2 5 query 2 5 add 3 5 query 1 5 add 2 4 query 1 4 add 2 5 query 2 5 add 2 2 query 1 5Sample Output
1 1 2 4 4 6
题意:题目给你N个数,Q个操作,另外有个数组a,a 的初始值都是0,然后Q个操作,若是add 则在区间x~y之间的a[]都加一,query 就查找l~r之间 ∑ri=l⌊ai/bi⌋∑i=lr⌊ai/bi⌋;
题解: 由于是取下界,我们可以求每个区间内距离该位置上b[i]值最近的数,然后没加一,就把b[i]减一,如果最小值为零,就出现了a[i]/b[i]==1的情况,就将区间的sum加一,对于
每个查询操作,我们只要求区间的sun和即可;
参考代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 int n,q,x,y,b[maxn]; 5 char str[10]; 6 7 struct Node{ 8 int l,r,sum,tag,minnumm; 9 } tree[maxn<<2]; 10 11 void build(int l,int r,int pos) 12 { 13 tree[pos].l=l,tree[pos].r=r; 14 if(l==r) 15 { 16 tree[pos].minnumm=b[l]; 17 tree[pos].sum=0; 18 tree[pos].tag=0; 19 return ; 20 } 21 int mid=(l+r)>>1; 22 build(l,mid,pos<<1); 23 build(mid+1,r,pos<<1|1); 24 tree[pos].minnumm=min(tree[pos<<1].minnumm,tree[pos<<1|1].minnumm); 25 tree[pos].sum=tree[pos<<1].sum+tree[pos<<1|1].sum; 26 tree[pos].tag=tree[pos<<1].tag+tree[pos<<1|1].tag; 27 } 28 29 void pushdown(int pos) 30 { 31 tree[pos<<1].minnumm+=tree[pos].tag; 32 tree[pos<<1|1].minnumm+=tree[pos].tag; 33 tree[pos<<1].tag+=tree[pos].tag; 34 tree[pos<<1|1].tag+=tree[pos].tag; 35 tree[pos].tag=0; 36 } 37 38 void update(int pos,int l,int r,bool temp) 39 { 40 if(tree[pos].l==l&&tree[pos].r==r) 41 { 42 if(temp) 43 { 44 tree[pos].tag--; 45 tree[pos].minnumm--; 46 } 47 if(tree[pos].minnumm>0) return ; 48 if(tree[pos].l==tree[pos].r) 49 { 50 if(tree[pos].minnumm==0) tree[pos].minnumm=b[tree[pos].l],tree[pos].sum++; 51 return ; 52 } 53 temp=false; 54 } 55 56 if(tree[pos].tag) pushdown(pos); 57 58 int mid=(tree[pos].l+tree[pos].r)>>1; 59 if(r<=mid) update(pos<<1,l,r,temp); 60 else if(l>=mid+1) update(pos<<1|1,l,r,temp); 61 else update(pos<<1,l,mid,temp),update(pos<<1|1,mid+1,r,temp); 62 63 tree[pos].minnumm=min(tree[pos<<1].minnumm,tree[pos<<1|1].minnumm); 64 tree[pos].sum=tree[pos<<1].sum+tree[pos<<1|1].sum; 65 } 66 67 int query(int pos,int l,int r) 68 { 69 if(tree[pos].tag) pushdown(pos); 70 if(tree[pos].l==l&&tree[pos].r==r) return tree[pos].sum; 71 int mid=(tree[pos].l+tree[pos].r)>>1,ans=0; 72 if(r<=mid) ans+=query(pos<<1,l,r); 73 else if(l>=mid+1) ans+=query(pos<<1|1,l,r); 74 else ans+=query(pos<<1,l,mid)+query(pos<<1|1,mid+1,r); 75 return ans; 76 } 77 78 int main() 79 { 80 while(~scanf("%d%d",&n,&q)) 81 { 82 for(int i=1;i<=n;i++) scanf("%d",b+i); 83 build(1,n,1); 84 while(q--) 85 { 86 scanf("%s%d%d",str,&x,&y); 87 if(str[0]=='a') update(1,x,y,true); 88 else if(str[0]=='q') printf("%d ",query(1,x,y)); 89 } 90 } 91 return 0; 92 }