hdu6315 Naive Operations
题目链接:戳我
给你两个序列a,b,其中a初始是全空的,b是一个排列。
现在有两种操作:
1、给一个区间的a数组加上1
2、求一个区间\(\sum a[i]/b[i]\)
区间操作想到用数据结构维护。
我们可以知道,\(a[i]/b[i]\)只有在a[i]增加够一个b[i]的时候才会多1的贡献,但是我们再增加a[i]的时候和b[i]进行比较比较麻烦(但其实也应该是可以做的),所以我们考虑转化成b[i]-1。
如果b[i]的区间最小值大于1,直接区间减法即可。如果不是,那么寻找那个值为1的,把它改成初始b[i]。
具体见代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define MAXN 100010
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
return x*f;
}
int n,q;
int a[MAXN],b[MAXN];
struct Node{long long sum,valb,minn,tag;}t[MAXN<<2];
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
inline void push_up(int x)
{
t[x].minn=min(t[ls(x)].minn,t[rs(x)].minn);
t[x].sum=t[ls(x)].sum+t[rs(x)].sum;
}
inline void push_down(int x)
{
if(t[x].tag)
{
t[ls(x)].tag+=t[x].tag;
t[rs(x)].tag+=t[x].tag;
t[ls(x)].minn-=t[x].tag;
t[rs(x)].minn-=t[x].tag;
t[x].tag=0;
}
}
inline void build(int x,int l,int r)
{
t[x].tag=t[x].sum=0;
if(l==r)
{
t[x].minn=t[x].valb=b[l];
t[x].sum=0;
return;
}
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
push_up(x);
}
inline void update(int x,int l,int r,int ll,int rr)
{
if(ll<=l&&r<=rr&&t[x].minn>1)
{
t[x].tag++;
t[x].minn--;
return;
}
if(l==r&&t[x].minn==1)
{
t[x].sum++;
t[x].minn=t[x].valb;
t[x].tag=0;
return;
}
int mid=(l+r)>>1;
push_down(x);
if(ll<=mid) update(ls(x),l,mid,ll,rr);
if(mid<rr) update(rs(x),mid+1,r,ll,rr);
push_up(x);
}
inline long long query(int x,int l,int r,int ll,int rr)
{
if(ll<=l&&r<=rr) return t[x].sum;
int mid=(l+r)>>1;
push_down(x);
long long cur_ans=0;
if(ll<=mid) cur_ans+=query(ls(x),l,mid,ll,rr);
if(mid<rr) cur_ans+=query(rs(x),mid+1,r,ll,rr);
return cur_ans;
}
int main()
{
while(~scanf("%d%d",&n,&q))
{
for(int i=1;i<=n;i++) b[i]=read();
build(1,1,n);
while(q--)
{
string str;
cin>>str;
// cout<<str<<endl;
int l=read(),r=read();
if(str[0]=='a') update(1,1,n,l,r);
else printf("%lld\n",query(1,1,n,l,r));
}
}
return 0;
}