• CF1004F Sonya and Bitwise OR 线段树


    链接

    题意:

    题解:

    • 看起来很像是一棵线段树
    • 或只会越来越大  一共也只有log级别 所以可以给每个点开一个vector 保存前缀和后缀  保证每个vector里面不超过二十个  所以复杂度是够的
    • 合并答案的时候只要枚举左区间的后缀和右区间的前缀即可  
    • 合并后缀的时候只要 先设置temp为右子树的后缀  然后枚举左子树的后缀  与 当前后缀的最后一个比较即可  如果是一样的放在一起  不一样或上去  所以对于前缀和后缀的vector来说  越后面的数字一越多!!!
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+100;
    #define ll long long
    int n,m,x,a[N];
    struct node
    {
        vector<pair<int,int> >pre,last;
        ll ans;
        node(){ans=0;}
    }t[N<<2];
    ll getans(node &a,node &b)
    {
        ll ans=0;
        for(auto &i:a.last)for(auto &j:b.pre)
        if((i.first|j.first)>=x)ans+=(ll)i.second*(ll)j.second;
        return ans;
    }
    node push_up(node &a,node &b)
    {    
        if(a.last.size()==0)return b;
        if(b.last.size()==0)return a;
        node temp;
        temp.ans=a.ans+b.ans;
        temp.ans+=getans(a,b);
    
        temp.last=b.last;
        int u=temp.last.back().first;
        for(auto &v: a.last)
        {    
            if((v.first|u)==u)temp.last.back().second+=v.second;
            else temp.last.push_back({(v.first|u),v.second}),u=(u|v.first);
        }
        temp.pre=a.pre;
        u=temp.pre.back().first;
        for(auto &v: b.pre)
        {
            if((v.first|u)==u)temp.pre.back().second+=v.second;
            else temp.pre.push_back({(v.first|u),v.second}),u=(u|v.first);
        }
        return temp;
    }
    void build(int l,int r,int pos)
    {
        if(l==r)
        {    
            t[pos].last.push_back({a[l],1});
            t[pos].pre.push_back({a[l],1});
            t[pos].ans=a[l]>=x;
            return ;
        }
        int m=(l+r)>>1;
        build(l,m,pos<<1);build(m+1,r,pos<<1|1);
        t[pos]=push_up(t[pos<<1],t[pos<<1|1]);
    }
    void upnode(int xx,int v,int l,int r,int pos)
    {
        if(l==r)
        {    
            a[l]=v;
            t[pos].ans=a[l]>=x;
            t[pos].pre.clear();t[pos].last.clear();
            t[pos].pre.push_back({v,1});
            t[pos].last.push_back({v,1});
            return ;
        }
        int m=(l+r)>>1;
        if(xx<=m)upnode(xx,v,l,m,pos<<1);
        else upnode(xx,v,m+1,r,pos<<1|1);
        t[pos]=push_up(t[pos<<1],t[pos<<1|1]);
    }
    node qsum(int L,int R,int l,int r,int pos)
    {
        if(L<=l&&r<=R)return t[pos];
        int m=(l+r)>>1;
        node ans;
        if(L<=m)
        {
            node t=qsum(L,R,l,m,pos<<1);
            ans=push_up(t,ans);
        }
        if(R>m)
        {
            node t=qsum(L,R,m+1,r,pos<<1|1);
            ans=push_up(ans,t);
        }
        return ans;
    }
    int main()
    {    
        cin>>n>>m>>x;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        build(1,n,1);int op,u,v;
        while(m--)
        {
            scanf("%d%d%d",&op,&u,&v);
            if(op==1)upnode(u,v,1,n,1);
            else printf("%lld
    ",qsum(u,v,1,n,1).ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    update 大表
    Lazy Writer&CheckPoint
    SQLServer查看登录名和数据库的用户名的映射
    SQL Server Replication出现的错误:The process could not execute 'sp_replcmds' on 'WASYGSHA02-0186'.
    execute as login 切换上下文
    IOS开发-懒加载延迟加载-图片浏览器实例
    IOS开发-代码创建UI控件并修改控件属性(代码创建UIButton、UILabel)
    IOS开发-常用UI控件的基本使用(Transform形变属性、frame属性、center属性的使用)
    IOS开发-UI控件的常见属性
    IOS开发-UIView(视图)与UIViewController(视图控制器)
  • 原文地址:https://www.cnblogs.com/bxd123/p/11700504.html
Copyright © 2020-2023  润新知