2018 Multi-University Training Contest 2(Naive Operations ) hdu6315

题目连接:Naive Operations

题意,两个数组,一个a[]开始全为0,一个b[]为一个1~n的排列,有两种操作,把[L,R]的a全加1,第二种询问区间[L,R]a[i]/b[i]的和

题解:开一个线段树,最开始为b[i],维护最小值还有位置(有多个最小之时先保存最左边的),每一次更新都对范围的值-1,然后再开个树状数组保存答案,当某个位置 为0时这个位置就可以加1,然后重新置为b[i];,为什么这样不会超时呢(因为总共的操作n=1e5,n/1+n/2+n/2+....n/n,是个调和级数复杂度为nlogn)

  1 #include<bits/stdc++.h>
  2 #include<set>
  3 #include<cstdio>
  4 #include<iomanip>
  5 #include<iostream>
  6 #include<string>
  7 #include<cstring>
  8 #include<algorithm>
  9 #define pb push_back
 10 #define mk make_pair
 11 #define ll long long
 12 #define fi first
 13 #define se second
 14 #define PI 3.14159265
 15 #define ls l,m,rt<<1
 16 #define rs m+1,r,rt<<1|1
 17 #define eps 1e-7
 18 #define pii pair<int,int>
 19 typedef unsigned long long ull;
 20 const int mod=1e3+5;
 21 const ll inf=0x3f3f3f3f3f3f3f;
 22 const int maxn=1e5+5;
 23 using namespace std;
 24 int n,q;
 25 int tr[maxn<<2],pos[maxn<<2],b[maxn],laz[maxn<<2],an[maxn];//最小值,最值位置
 26 int lowbit(int x){return x&(-x);}
 27 int add(int x,int val){while(x<=n)an[x]+=val,x+=lowbit(x);}
 28 int get_sum(int x)
 29 {
 30     int ans=0;
 31     while(x>0){ans+=an[x],x-=lowbit(x);}
 32     return ans;
 33 }
 34 int query(int l,int r){return get_sum(r)-get_sum(l-1);};
 35 void init(){memset(an,0,sizeof(an));}
 36 void push_up(int rt)
 37 {
 38     if(tr[rt<<1]<=tr[rt<<1|1])
 39     {
 40         tr[rt]=tr[rt<<1];pos[rt]=pos[rt<<1];
 41     }
 42     else
 43     {
 44         tr[rt]=tr[rt<<1|1];pos[rt]=pos[rt<<1|1];
 45     }
 46 }
 47 void push_down(int rt)
 48 {
 49     if(laz[rt]!=0)
 50     {
 51         laz[rt<<1]+=laz[rt];
 52         laz[rt<<1|1]+=laz[rt];
 53         tr[rt<<1]-=laz[rt];
 54         tr[rt<<1|1]-=laz[rt];
 55         laz[rt]=0;
 56     }
 57 }
 58 void built(int l,int r,int rt)
 59 {
 60     laz[rt]=0;
 61     if(l==r)
 62     {
 63         pos[rt]=l;
 64         tr[rt]=b[l];return ;
 65     }
 66     int m=(l+r)>>1;
 67     built(ls);built(rs);
 68     push_up(rt);
 69 }
 70 void update(int L,int R,int val,int l,int r,int rt)
 71 {
 72     if(L<=l&&r<=R)
 73     {
 74         tr[rt]-=val;
 75         laz[rt]+=val;return ;
 76     }
 77     push_down(rt);
 78     int m=(l+r)>>1;
 79     if(L<=m)update(L,R,val,ls);
 80     if(R>m) update(L,R,val,rs);
 81     push_up(rt);
 82 }
 83 pii query(int L,int R,int l,int r,int rt)
 84 {
 85     if(L<=l&&r<=R)
 86     {
 87         return mk(tr[rt],pos[rt]);
 88     }
 89     push_down(rt);
 90     int m=(l+r)>>1;pii ans;ans.fi=1e9;
 91     if(L<=m)ans=min(ans,query(L,R,ls));
 92     if(R>m)ans=min(ans,query(L,R,rs));
 93     return ans;
 94 }
 95 int main()
 96 {
 97     while(~scanf("%d %d",&n,&q))
 98     {
 99         init();
100         for(int i=1;i<=n;i++)scanf("%d",b+i);
101         built(1,n,1);
102         while(q--)
103         {
104             char op[100];int x,y;
105             scanf("%s %d %d",op,&x,&y);
106             if(op[0]=='a')
107             {
108                 update(x,y,1,1,n,1);
109                 int l=x,r=y;
110                 while(l<=r)
111                 {
112                     pii tmp=query(l,r,1,n,1);
113                     if(tmp.fi==0)
114                     {
115                         update(tmp.se,tmp.se,-b[tmp.se],1,n,1);
116                         l=tmp.se+1;
117                         add(tmp.se,1);
118                     }
119                     else break;
120                 }
121             }
122             else
123             {
124                 printf("%d\n",query(x,y));
125             }
126         }
127     }
128     return 0;
129 }

猜你喜欢

转载自www.cnblogs.com/lhclqslove/p/9371275.html