链接:
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; }