zoukankan      html  css  js  c++  java
  • 2020牛客寒假算法基础集训营3【F、G】-牛牛的Link Power I/II(线段树)

    题目链接:F:https://ac.nowcoder.com/acm/contest/3004/F

    G:https://ac.nowcoder.com/acm/contest/3004/G

    先讲F:

    从前向后遍历,每遇到一个1就先增加当前贡献值然后记录当前个数,遇到每个数字增加当前1的个数作为贡献值。也可以计算前缀和的前缀和等方法。

    然后是G:

    在F的基础上用线段树维护对应区间1的个数cnt和下标总和ind。当pos下标的数字从0变为1时,左边的贡献增加pos*2-(cnt+ind),右边的贡献增加(cnt+ind)-pos*2。(cnt和ind分别指对应区间的值);当pos下标的数字从1变为0时,贡献对应减少。

    (史前巨坑,负数取模,WA到吐,怀疑人生。。。以后遇到取模的时候要注意QAQ)

    附上G题代码(F题就是main函数上半部分):

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef pair<ll,ll> pll;
     5 const int mod=1e9+7,maxn=1e5+10;
     6 inline int ls(signed x){return x<<1;}
     7 inline int rs(signed x){return x<<1|1;}
     8 struct Node{
     9     int l,r;
    10     ll val;
    11 };
    12 Node cnt[maxn<<2];
    13 Node ind[maxn<<2];
    14 char ch[maxn];
    15 ll pls(ll a,ll b){//有坑,防止a+b是负数
    16     return ((a+b)%mod+mod)%mod;
    17 }
    18 void pushup(int root){
    19     cnt[root].val=pls(cnt[ls(root)].val,cnt[rs(root)].val);
    20     ind[root].val=pls(ind[ls(root)].val,ind[rs(root)].val);
    21 }
    22 void build(int root,int l,int r){
    23     cnt[root].l=ind[root].l=l;
    24     cnt[root].r=ind[root].r=r;
    25     if(l==r){
    26         if(ch[l]=='1'){
    27             cnt[root].val=1;
    28             ind[root].val=l;
    29         }else{
    30             cnt[root].val=ind[root].val=0;
    31         }
    32         return;
    33     }
    34     int mid=(l+r)>>1;
    35     build(ls(root),l,mid);
    36     build(rs(root),mid+1,r);
    37     pushup(root);
    38 }
    39 void update(int root,int l,int r,int pos){
    40     if(l==r){
    41         cnt[root].val=1-cnt[root].val;
    42         ind[root].val=l-ind[root].val;
    43         return;
    44     }
    45     int mid=(l+r)>>1;
    46     if(pos<=mid)update(ls(root),l,mid,pos);
    47     else update(rs(root),mid+1,r,pos);
    48     pushup(root);
    49 }
    50 pll operator +(pll a,pll b){
    51     return {pls(a.first,b.first),pls(a.second,b.second)};
    52 }
    53 pll query(int root,int l,int r){
    54     assert(r>=l);
    55     int mid=(cnt[root].l+cnt[root].r)>>1;
    56     if(cnt[root].l==l&&cnt[root].r==r)
    57         return {cnt[root].val,ind[root].val};
    58     if(mid>=r)return query(ls(root),l,r);
    59     else if(mid<l)return query(rs(root),l,r);
    60     else return query(ls(root),l,mid)+query(rs(root),mid+1,r);
    61 }
    62 int main(){
    63     int n;
    64     scanf("%d%s",&n,ch+1);
    65     build(1,1,n);
    66     ll cont=0,t=0,res=0;
    67     for(int i=1;i<=n;i++){
    68         if(ch[i]=='1'){
    69             res=pls(res,t);
    70             cont++;
    71         }
    72         t=pls(cont,t);
    73     }
    74     cout<<res<<"
    ";
    75     int m;
    76     cin>>m;
    77     while(m--){
    78         int q,pos;
    79         cin>>q>>pos;
    80         update(1,1,n,pos);
    81         if(q==1){
    82             pll a(0,0),b(0,0);
    83             if(pos!=1)a=query(1,1,pos-1);
    84             if(pos!=n)b=query(1,pos+1,n);
    85             res=pls(res,pos*a.first-a.second-pos*b.first+b.second);
    86         }else{
    87             pll a(0,0),b(0,0);
    88             if(pos!=1)a=query(1,1,pos-1);
    89             if(pos!=n)b=query(1,pos+1,n);
    90             res=pls(res,-(pos*a.first-a.second-pos*b.first+b.second));
    91         }
    92         cout<<res<<"
    ";
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    @override报错
    idea快捷键
    java中getAttribute与getParameter的区别
    localStorage基于浏览器的本地存储
    js画布组件(<canvas></canvas>)
    easyui
    关于Bootstrap
    使用layUI美化的登录功能
    EXT JS
    ★一些文章链接
  • 原文地址:https://www.cnblogs.com/charles1999/p/12285143.html
Copyright © 2011-2022 走看看