|
Naive OperationsTime Limit: 6000/3000 MS (Java/Others) Memory Limit: 502768/502768 K (Java/Others)Total Submission(s): 3079 Accepted Submission(s): 1358 Problem Description In a galaxy far, far away, there are two integer sequence a and b of length n.
Input There are multiple test cases, please read till the end of input file.
Output Output the answer for each 'query', each one line.
Sample Input 5 12 1 5 2 4 3 add 1 4 query 1 4 add 2 5 query 2 5 add 3 5 query 1 5 add 2 4 query 1 4 add 2 5 query 2 5 add 2 2 query 1 5
Sample Output 1 1 2 4 4 6
Source 2018 Multi-University Training Contest 2
Recommend chendu | We have carefully selected several similar problems for you: 6396 6395 6394 6393 6392
|
终于学会了线段树的原理与操作了,真的是慢的可以了,这个知识点好久之前就接触了,一直迷迷糊糊的.......
题意:有一个空的数组a和一个n个元素的数组b,有两个操作,第一个操作是从l到r这个区间中ai++,另一个操作是统计l到r中ai/bi的和,这道题只需要一个能支持区间修改和区间查询的线段树即可,用线段树维护的是ai/bi和b数组的区间最小值,当进行第一个操作的时候,只需要将那个区间的min--,当发现减到0的时候,当前位置的ans++,同时将当前位置的min再次更新到b,查询的时候直接统计ans的区间和即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
typedef long long ll;
int tree[maxn<<2],a[maxn],lazy[maxn],ans[maxn],n;
void pushup(int rt)
{
tree[rt]=min(tree[rt<<1],tree[rt<<1|1]);
ans[rt]=ans[rt<<1]+ans[rt<<1|1];
}
void pushdown(int rt)
{
if(lazy[rt])
{
tree[rt<<1]-=lazy[rt];
tree[rt<<1|1]-=lazy[rt];
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
lazy[rt]=0;
}
}
void build(int l,int r,int rt)
{
ans[rt]=0;
lazy[rt]=0;
if(l==r)
{
scanf("%d",&a[rt]);
tree[rt]=a[rt];
return;
}
int m=l+r>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
pushup(rt);
}
void update(int L,int R,int l=1,int r=n,int rt=1)
{
if(l>=L && r<=R)
{
tree[rt]--;
if(tree[rt])
{
lazy[rt]++;
return;
}
else
{
if(l==r)
{
ans[rt]++;
tree[rt]=a[rt];
return;
}
}
}
int m=l+r>>1;
pushdown(rt);
if(L<=m)
update(L,R,l,m,rt<<1);
if(R>m)
update(L,R,m+1,r,rt<<1|1);
pushup(rt);
}
int query(int L,int R,int l=1,int r=n,int rt=1)
{
if(l>=L && r<=R)
return ans[rt];
int m=l+r>>1;
int sum=0;
if(L<=m)
sum+=query(L,R,l,m,rt<<1);
if(R>m)
sum+=query(L,R,m+1,r,rt<<1|1);
return sum;
}
int main()
{
int q;
while(scanf("%d%d",&n,&q)==2)
{
build(1,n,1);
while(q--)
{
char s[20];
scanf("%s",s);
if(s[0]=='a')
{
int a,b;
scanf("%d%d",&a,&b);
update(a,b);
}
else
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",query(a,b));
}
}
}
return 0;
}