【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           

 

posted on 2018-07-31 16:05  myx12345  阅读(172)  评论(0编辑  收藏  举报

导航