#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
using namespace std;
const int maxn=222222;
int Max[maxn<<2];
void PushUp(int rt) //向上更新
{
Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
void build(int l,int r,int rt) // 建立线段树
{
if(l==r)
{
scanf("%d",&Max[rt]);
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int p,int v,int l,int r,int rt) //单点更新
{
if(l==r)
{
Max[rt]=v;
return ;
}
int m=(l+r)>>1;
if(p<=m) update(p,v,lson);
else update(p,v,rson);
PushUp(rt);
}
int query(int L,int R,int l,int r,int rt) // 区间最大值查询
{
if(L<=l&&r<=R)
{
return Max[rt];
}
int m=(l+r)>>1;
int ans=0;
if(L<=m) ans=max(ans,query(L,R,lson));
if(R>m) ans=max(ans,query(L,R,rson));
return ans;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
build(1,n,1);
for(int i=0;i<m;i++)
{
char c[15];
int x,y;
scanf("%s%d%d",c,&x,&y);
if(c[0]=='Q') printf("%d\n",query(x,y,1,n,1));
else update(x,y,1,n,1);
}
}
return 0;
}
叫你求,03,2,1的逆序数,3,2,1,0的逆序数,2,1,0,3的逆序数,1,0,3,2的逆序数 中最小的逆序数是什么。
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
using namespace std;
const int maxn=5005;
int sum[maxn<<2],x[maxn];
void PushUp(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt)
{
sum[rt]=0;
if(l==r) return ;
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int p,int l,int r,int rt)
{
if(l==r)
{
sum[rt]++;
return ;
}
int m=(l+r)>>1;
if(p<=m) update(p,lson);
else update(p,rson);
PushUp(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return sum[rt];
}
int m=(l+r)>>1;
int ans=0;
if(L<=m) ans+=query(L,R,lson);
if(R>m) ans+=query(L,R,rson);
return ans;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
build(0,n-1,1);
int sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&x[i]);
sum+=query(x[i]+1,n-1,0,n-1,1);
update(x[i],0,n-1,1);
}
int ans=sum;
for(int i=0;i<n;i++)
{
sum+=n-1-x[i]-x[i];
ans=min(ans,sum);
}
printf("%d\n",ans);
}
return 0;
}
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
using namespace std;
const int maxn=100005;
LL add[maxn<<2],sum[maxn<<2];
void PushUp(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(int rt,int m)
{
if(add[rt])
{
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
sum[rt<<1]+=(m-(m>>1))*add[rt];
sum[rt<<1|1]+=(m>>1)*add[rt];
add[rt]=0;
}
}
void build(int l,int r,int rt)
{
add[rt]=0;
if(l==r)
{
scanf("%lld",&sum[rt]);
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int L,int R,int x,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
sum[rt]+=(LL)((r-l+1)*x);
add[rt]+=(LL)x;
return ;
}
PushDown(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m) update(L,R,x,lson);
if(R>m) update(L,R,x,rson);
PushUp(rt);
}
LL query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return sum[rt];
}
PushDown(rt,r-l+1);
int m=(l+r)>>1;
LL ans=0;
if(L<=m) ans+=query(L,R,lson);
if(R>m) ans+=query(L,R,rson);
return ans;
}
int main()
{
int n,m,x,y,v;
char op[5];
while(~scanf("%d%d",&n,&m))
{
build(1,n,1);
for(int i=0;i<m;i++)
{
scanf("%s",op);
if(op[0]=='Q') scanf("%d%d",&x,&y),printf("%lld\n",query(x,y,1,n,1));
else scanf("%d%d%d",&x,&y,&v),update(x,y,v,1,n,1);
}
}
return 0;
}
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
using namespace std;
const int maxn=100005,inf=1<<29;
int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2],ln[maxn<<2],rn[maxn<<2];
void PushUp(int rt,int m)//利用子节点信息更新父节点
{
lsum[rt]=lsum[rt<<1];//根节点从左边其的最长区间至少等于左儿子从左边起得最长区间
rsum[rt]=rsum[rt<<1|1];
msum[rt]=max(msum[rt<<1],msum[rt<<1|1]);
ln[rt]=ln[rt<<1];
rn[rt]=rn[rt<<1|1];
if(rn[rt<<1]<ln[rt<<1|1])//左儿子区间右端点比右儿子区间左端点小
{
if(lsum[rt]==m-(m>>1)) lsum[rt]+=lsum[rt<<1|1];
if(rsum[rt]==(m>>1)) rsum[rt]+=rsum[rt<<1];
msum[rt]=max(msum[rt],rsum[rt<<1]+lsum[rt<<1|1]);
}
}
void build(int l,int r,int rt)//建树
{
if(l==r)
{
scanf("%d",&ln[rt]);
//printf("[%d,%d] = %d\n",l,r,ln[rt]);
rn[rt]=ln[rt];
lsum[rt]=rsum[rt]=msum[rt]=1;
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt,r-l+1);
//printf("msum[%d,%d] = %d\n",l,r,msum[rt]);
}
void update(int p,int x,int l,int r,int rt)//单点更新
{
if(l==r)
{
lsum[rt]=rsum[rt]=msum[rt]=1;
ln[rt]=rn[rt]=x;
return ;
}
int m=(l+r)>>1;
if(p<=m) update(p,x,lson);
else update(p,x,rson);
PushUp(rt,r-l+1);
}
int Query(int L,int R,int l,int r,int rt)
{
//区间是叶子节点或都可用或都不可用直接返回
if(L<=l&&r<=R) return msum[rt];
//if(l==r||msum[rt]==0||msum[rt]==r-l+1) return msum[rt];
int ans=0;
int m=(l+r)>>1;
if(L<=m) ans=max(ans,Query(L,R,lson));
if(R>m) ans=max(ans,Query(L,R,rson));
if(rn[rt<<1]<ln[rt<<1|1]) ans=max(ans,min(rsum[rt<<1],m-L+1)+min(lsum[rt<<1|1],R-m));//不能越了区间[L,R]的界
//printf("msum[%d,%d] = %d ans=%d\n",l,r,msum[rt],ans);
return ans;
//return max(ans,rsum[rt<<1]+lsum[rt<<1|1]);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//srand(time(NULL));
int n,m,x,y,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
char op[5];
build(1,n,1);
for(int i=0;i<m;i++)
{
scanf("%s%d%d",op,&x,&y);
if(op[0]=='U') update(x+1,y,1,n,1);
else printf("%d\n",Query(x+1,y+1,1,n,1));
}
}
return 0;
}