题目连接: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 }
原文地址:https://www.cnblogs.com/lhclqslove/p/9371275.html
时间: 2024-10-02 01:11:04