In a galaxy far, far away, there are two integer sequence a and b of length n.
b is a static permutation of 1 to n. Initially a is filled with zeroes.
There are two kind of operations:
题意:
就是我们有一个初始为零的区间和一个静态的区间 执行的操作有两种 一种是对初始为零的区间进行修改 一种是查询区间和 但这个区间和并不是一般的区间和 而是(ai/bi)的区间和
思路:
因为我们初始的两个区间大小相同 所以我们可以直接用线段树去维护我们需要的答案 如果不是维护一个答案 而是用两棵线段树则无法在query操作得到我们想要的答案 分析到这里 我们需要爱update操作的时候对每一个叶子节点进行判断 如果ai/bi大于1 则表示答案应该更新 同时记得给bi加上一个相应的初始值 为下一次更新做准备 这样来得到我们最后的答案
AC代码
#include
#include
#include
using namespace std;
const int maxn=100000+5;
int book[maxn];
char ch[10];
#define lson (q<<1)
#define rson (q<<1|1)
#define mid ((l+r)>>1)
int m,n;
int tmpa,tmpb;
struct node
{
int Max,Min;
int val;
int flag;
};
struct node segt[maxn<<2];
void push_up(int q)
{
segt[q].Max=max(segt[lson].Max,segt[rson].Max);
segt[q].Min=min(segt[lson].Min,segt[rson].Min);
segt[q].val=segt[lson].val+segt[rson].val;
}
void build_tree(int q,int l,int r)
{
segt[q].flag=0;
if(l==r)
{
segt[q].Max=0;
segt[q].Min=book[l];
segt[q].val=0;
return; //第一遍忘记写了
}
int m=mid;
build_tree(lson,l,m);
build_tree(rson,m+1,r);
push_up(q);
return;
}
void push_down(int q)
{
if(segt[q].flag)
{
segt[lson].flag+=segt[q].flag;
segt[rson].flag+=segt[q].flag;
segt[lson].Max+=segt[q].flag;
segt[rson].Max+=segt[q].flag;
segt[q].flag=0;
}
}
void update(int q,int l,int r,int a,int b)
{
if(l>=a && r<=b)
{
segt[q].Max+=1;
if(segt[q].Max<segt[q].Min)
{
segt[q].flag++;
return; //线段树中我们总要去对能优化的部分去做出优化 这可能就是ac与超时的距离
}
if(segt[q].Max>=segt[q].Min && l==r)
{
segt[q].val++;
segt[q].Min+=book[l];//为下一次这个叶子节点上的值改变做准备
return;
}
}
push_down(q);
int m=mid;
if(a<=m) update(lson,l,m,a,b);
if(b>m) update(rson,m+1,r,a,b);
push_up(q);
return ;
}
int query(int q,int l,int r,int a,int b)
{
if(l>=a && r<=b)
{
return segt[q].val;
}
push_down(q);
int m=mid;
int ans=0;
if(a<=m) ans+=query(lson,l,m,a,b);
if(b>m) ans+=query(rson,m+1,r,a,b);
return ans;
}
int main()
{
while(~scanf("%d %d",&m,&n))
{
memset(segt,0,sizeof(segt));
for(int i=1;i<=m;i++)
{
scanf("%d",&book[i]);
}
build_tree(1,1,m);
while(n--)
{
scanf("%s %d %d",ch,&tmpa,&tmpb);
if(ch[0]=='a')
{
update(1,1,m,tmpa,tmpb);
}
else
{
printf("%d\n",query(1,1,m,tmpa,tmpb));
}
}
}
return 0;
}