链接:
https://www.nowcoder.com/acm/contest/112/D
来源:牛客网
来源:牛客网
题目描述
一个只含数字的字符串,q次操作,每次操作将第i位数字改为x,每次操作后,统计长度在[l, r]之间且首数字大于尾数字的子串的个数。
输入描述:
第一行一个只含数字的字符串; 第二行3个整数q, l, r; 接下来q行,每行两个整数i, x。
输出描述:
输出q行,每行一个整数,表示长度在[l, r]之间且首数字大于尾数字的子串的个数。
题解:
更改i位置的数为x,查询left~i大于x的数有多少个,
查询i~right小于x的数有几个。
注意左右边界的确定问题,防止越界。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+7;
char t[maxn];
int a[maxn];
struct node
{
int left,right,mid;
int x[12];
}tree[maxn<<2];
void push_up(int rt)
{
for(int i=0;i<=9;i++)
tree[rt].x[i]=tree[rt<<1].x[i]+tree[rt<<1|1].x[i];
}
void build(int l,int r,int rt)
{
tree[rt].left=l;
tree[rt].right=r;
tree[rt].mid=(l+r)>>1;
if(l==r)
{
for(int i=9;i>=0;i--)
{
if(i==a[l])
tree[rt].x[i]=1;
else
tree[rt].x[i]=0;
}
return;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
push_up(rt);
}
int query(int l,int r,int rt,int k)
{
if(tree[rt].left>=l&&tree[rt].right<=r)
{
ll ans=0;
for(int i=9;i>k;i--)
ans+=tree[rt].x[i];
return ans;
}
ll s=0;
if(l<=tree[rt].mid)
s+=query(l,r,rt<<1,k);
if(r>tree[rt].mid)
s+=query(l,r,rt<<1|1,k);
return s;
}
void update(int L,int rt,int k)
{
if(tree[rt].left==tree[rt].right)
{
for(int i=9;i>=0;i--)
{
if(i==k)
tree[rt].x[i]=1;
else
tree[rt].x[i]=0;
}
return;
}
if(L<=tree[rt].mid)
update(L,rt<<1,k);
else
update(L,rt<<1|1,k);
push_up(rt);
}
int main()
{
scanf("%s",t+1);
int len=strlen(t+1);
int l,r;
int Q;scanf("%d",&Q);
scanf("%d%d",&l,&r);
for(int i=1;i<=len;i++)
a[i]=t[i]-'0';
build(1,len,1);
ll ans=0;
for(int i=1;i<=len;i++)
{
int L1=max(1,i-r+1),R1=max(1,i-l+1);
ll x1=0,x2=0,x3=0;
if(i-R1+1<l)R1=i+1-l;
if(i-L1+1>r)L1=i+1-r;
if(i!=1)x1=query(L1,R1,1,a[i]);
L1=min(len,i+l-1);R1=min(len,i+r-1);
if(R1-i+1>r)R1=r+i-1;
if(L1-i+1<l)L1=l+i-1;
if(i!=len)
{
x2=query(L1,R1,1,-1);
x3=query(L1,R1,1,a[i]-1);
}
ans=ans+x1+x2-x3;
}
ans/=2;
while(Q--)
{
int i,x;
scanf("%d%d",&i,&x);
ll ans1,ans2;
int L1=max(1,i-r+1),R1=max(1,i-l+1);
ll x1=0,x2=0,x3=0;
if(i-R1+1<l)R1=i+1-l;
if(i-L1+1>r)L1=i+1-r;
if(i!=1)x1=query(L1,R1,1,a[i]);
L1=min(len,i+l-1);R1=min(len,i+r-1);
if(R1-i+1>r)R1=r+i-1;
if(L1-i+1<l)L1=l+i-1;
if(i!=len)
{
x2=query(L1,R1,1,-1);
x3=query(L1,R1,1,a[i]-1);
}
a[i]=x;
ans1=x1+x2-x3;
update(i,1,x);
L1=max(1,i-r+1),R1=max(1,i-l+1);
x1=0,x2=0,x3=0;
if(i-R1+1<l)R1=i+1-l;
if(i-L1+1>r)L1=i+1-r;
if(i!=1)x1=query(L1,R1,1,x);
L1=min(len,i+l-1);R1=min(len,i+r-1);
if(R1-i+1>r)R1=r+i-1;
if(L1-i+1<l)L1=l+i-1;
if(i!=len)
{
x2=query(L1,R1,1,-1);
x3=query(L1,R1,1,x-1);
}
ans2=x1+x2-x3;
ans=ans+ans2-ans1;
printf("%lld\n",ans);
}
return 0;
}