• 2020牛客寒假算法基础集训营3 G.牛牛的Link Power II (树状数组维护前缀和)


    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 }
     
  • 相关阅读:
    <<网络是怎样连接的>>笔记第一章browser生成message
    豆知识( DNS; HTTP入门;网络协议)
    日期和时间的操作
    类型转换
    分组查询
    存储过程
    触发器
    表连接
    变量
    union以及一些扩展
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12308585.html
Copyright © 2020-2023  润新知