https://ac.nowcoder.com/acm/contest/3004/G
发现每个“1”对于它本身位置产生的影响贡献为0,对前面的“1”有产生贡献,对后面的"1"也产生贡献,用三个树状数组去维护,第一个维护“1”的个数,第二个每个“1”的位置,第三个维护“1”的贡献的前缀和,对于每个“1”的贡献,计算出对前面1的贡献和对后面1的贡献,之和在第一个树状数组中更新这个位置1的个数,第二个树状数组中更新这个1的pos,第三个树状数组中就是更新这个“1”对答案的贡献了
1 #include<bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 const ll mod = 1e9+7; 5 const int maxn = 1e5+5; 6 ll c1[maxn],c2[maxn],c3[maxn]; 7 int n; 8 ll lowbit(ll x){ 9 return x&-x; 10 } 11 void add1(ll x, ll k) { 12 while (x <= n) { //不能越界 13 c1[x] = c1[x] + k; 14 x = x + lowbit(x); 15 } 16 } 17 void add2(ll x, ll k) { 18 while (x <= n) { //不能越界 19 c2[x] = (c2[x] + k); 20 x = x + lowbit(x); 21 } 22 } 23 void add3(ll x,ll k){ 24 while (x <= n) { //不能越界 25 c3[x] = (c3[x] + k); 26 x = x + lowbit(x); 27 } 28 } 29 ll getsum1(int x) { // a[1]……a[x]的和 30 ll ans = 0; 31 while (x >= 1) { 32 ans = ans + c1[x]; 33 x = x - lowbit(x); 34 } 35 return ans; 36 } 37 ll getsum2(int x) { // a[1]……a[x]的和 38 ll ans = 0; 39 while (x >= 1) { 40 ans = (ans + c2[x]); 41 x = x - lowbit(x); 42 } 43 return ans; 44 } 45 ll getsum3(int x) { // a[1]……a[x]的和 46 ll ans = 0; 47 while (x >= 1) { 48 ans = (ans + c3[x]); 49 x = x - lowbit(x); 50 } 51 return ans; 52 } 53 int main() 54 { 55 scanf("%d",&n); 56 string s; 57 cin>>s; 58 ll pos = 0,ans = 0,cnt = 0; 59 for(int i = 0;i<n;i++){ 60 if(s[i] == '1') add1(i+1,1),add2(i+1,i+1); 61 } 62 ll t = 0; 63 for(int i = 0;i<n;i++){ 64 if(s[i] == '1') cnt++,t = (t + i + 1),ans = ( cnt*(i+1) - t ),add3(i+1,ans); 65 } // pos = (pos + i)%mod,cnt++,ans = (ans + cnt*i-pos)%mod; 66 int m;scanf("%d",&m); 67 printf("%lld ",getsum3(n)%mod); 68 while(m--){ 69 ll q,pos; 70 cin>>q>>pos; 71 if(q == 1){ 72 add1(pos,1); 73 add2(pos,pos); 74 ll tmp = getsum1(pos)*pos-getsum2(pos); 75 tmp = ( tmp + (getsum2(n)-getsum2(pos) - (getsum1(n)-getsum1(pos))*pos)) ; 76 add3(pos,tmp); 77 } 78 else{ 79 ll tmp = getsum1(pos)*pos-getsum2(pos); 80 tmp = ( tmp + (getsum2(n)-getsum2(pos) - (getsum1(n)-getsum1(pos))*pos)) ; 81 add3(pos,-tmp); 82 add1(pos,-1); 83 add2(pos,-(pos)); 84 } 85 ll ans = getsum3(n)%mod; 86 printf("%lld ",ans); 87 } 88 return 0; 89 }