【HDOJ6315】Naive Operations(线段树,树状数组)
题意:
两个序列a和b,初始a[i]=0,b[i]给定且为一个1到n的排列,要求维护以下两种操作:
1.区间[L,R]内a[i]加1
2.询问[L,R]内a[i]/b[i](下取整)之和
n,q<=1e5
思路:
实际上a[i]/b[i]的线段树可以改为树状数组,因为只需要支持单点修改和前缀区间求和
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 const int N=110000; 21 int ad[N<<2],mn[N<<2],T[N],b[N],n,m,cas; 22 23 void pushdown(int p) 24 { 25 if(ad[p]) 26 { 27 ad[p<<1]+=ad[p]; 28 mn[p<<1]+=ad[p]; 29 ad[p<<1|1]+=ad[p]; 30 mn[p<<1|1]+=ad[p]; 31 ad[p]=0; 32 } 33 } 34 35 void pushup(int p) 36 { 37 mn[p]=min(mn[p<<1],mn[p<<1|1]); 38 } 39 40 void build(int l,int r,int p) 41 { 42 ad[p]=0; 43 if(l==r) 44 { 45 mn[p]=b[l]; 46 return; 47 } 48 int mid=(l+r)>>1; 49 build(l,mid,p<<1); 50 build(mid+1,r,p<<1|1); 51 pushup(p); 52 } 53 54 void modify(int x) 55 { 56 for(int i=x;i<=n;i+=i&-i) T[i]++; 57 } 58 59 int ask(int x) 60 { 61 int ans=0; 62 for(int i=x;i;i-=i&-i) ans+=T[i]; 63 return ans; 64 } 65 66 void update(int l,int r,int x,int y,int p) 67 { 68 if((x<=l)&&(r<=y)) 69 { 70 ad[p]--; 71 mn[p]--; 72 return; 73 } 74 pushdown(p); 75 int mid=(l+r)>>1; 76 if(x<=mid) update(l,mid,x,y,p<<1); 77 if(y>mid) update(mid+1,r,x,y,p<<1|1); 78 pushup(p); 79 } 80 81 void clear(int l,int r,int p) 82 { 83 if(l==r) 84 { 85 if(!mn[p]) 86 { 87 mn[p]=b[l]; 88 modify(l); 89 } 90 return; 91 } 92 pushdown(p); 93 int mid=(l+r)>>1; 94 if(!mn[p<<1]) clear(l,mid,p<<1); 95 if(!mn[p<<1|1]) clear(mid+1,r,p<<1|1); 96 pushup(p); 97 } 98 99 int main() 100 { 101 102 while(scanf("%d%d",&n,&m)!=EOF) 103 { 104 for(int i=1;i<=n;i++) scanf("%d",&b[i]); 105 build(1,n,1); 106 for(int i=1;i<=n;i++) T[i]=0; 107 for(int i=1;i<=m;i++) 108 { 109 char ch[10]; 110 scanf("%s",ch); 111 if(ch[0]=='a') 112 { 113 int l,r; 114 scanf("%d%d",&l,&r); 115 update(1,n,l,r,1); 116 clear(1,n,1); 117 } 118 else 119 { 120 int l,r; 121 scanf("%d%d",&l,&r); 122 printf("%d\n",ask(r)-ask(l-1)); 123 } 124 } 125 } 126 return 0; 127 } 128 129
null