zoukankan      html  css  js  c++  java
  • 牛客多校第十场 A Rikka with Lowbit 线段树

    链接:https://www.nowcoder.com/acm/contest/148/A
    来源:牛客网

    题目描述

    Today, Rikka is going to learn how to use BIT to solve some simple data structure tasks. While studying, She finds there is a magic expression in the template of BIT. After searching for some literature, Rikka realizes it is the implementation of the function .

    is defined on all positive integers. Let a1...am be the binary representation of x while a1 is the least significant digit, k be the smallest index which satisfies ak = 1. The value of is equal to 2k-1.

    After getting some interesting properties of , Rikka sets a simple data structure task for you:

    At first, Rikka defines an operator f(x), it takes a non-negative integer x. If x is equal to 0, it will return 0. Otherwise it will return or , each with the probability of .

    Then, Rikka shows a positive integer array A of length n, and she makes m operations on it.

    There are two types of operations:
    1. 1 L R, for each index i ∈ [L,R], change Ai to f(Ai).
    2. 2 L R, query for the expectation value of . (You may assume that each time Rikka calls f, the random variable used by f is independent with others.)

    输入描述:

    The first line contains a single integer t(1 ≤ t ≤ 3), the number of the testcases.

    The first line of each testcase contains two integers n,m(1 ≤ n,m ≤ 10
    5
    ). The second line contains n integers A
    i
    (1 ≤ A
    i
     ≤ 10
    8
    ). 

    And then m lines follow, each line contains three integers t,L,R(t ∈ {1,2}, 1 ≤ L ≤ R ≤ n).

    输出描述:

    For each query, let w be the expectation value of the interval sum, you need to output 
    . 

    It is easy to find that w x 2
    nm
     must be an integer.
    示例1

    输入

    复制
    1
    3 6
    1 2 3
    1 3 3
    2 1 3
    1 3 3
    2 1 3
    1 1 3
    2 1 3
    

    输出

    复制
    1572864
    1572864
    1572864

    分析:每次变化+-lowbit得到的期望是原结果,所以我们直接求一下区间和就可以
    AC代码:
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    const ll mod = 998244353;
     
    ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
     
    ll array1[maxn];
     
    struct node1
    {
        ll sum,addmark;
    } Node[maxn<<2];
    void pushup(int node)
    {
        Node[node].sum=Node[node<<1].sum+Node[node<<1|1].sum;
    }
    void buildtree(int node,int left,int right)
    {
        Node[node].addmark=0;
        if(left==right)
        {
            Node[node].sum=array1[left];
            return;
        }
        int m=(left+right)>>1;
        buildtree(node<<1,left,m);
        buildtree(node<<1|1,m+1,right);
        pushup(node);
    }
    void pushdown(int node,int left,int right)
    {
        if(Node[node].addmark)
        {
            int m=(left+right)>>1;
            Node[node<<1].addmark+=Node[node].addmark;
            Node[node<<1|1].addmark+=Node[node].addmark;
            Node[node<<1].sum+=(m-left+1)*Node[node].addmark;
            Node[node<<1|1].sum+=(right-m)*Node[node].addmark;
            Node[node].addmark=0;
        }
    }
    ll query(int node,int begin,int end,int left,int right)
    {
        if(left<=begin&&right>=end)
            return Node[node].sum;
        pushdown(node,begin,end);
        int m=(begin+end)>>1;//小心!!
        ll ans=0;
        if(left<=m)
            ans+=query(node<<1,begin,m,left,right);
        if(right>m)
            ans+=query(node<<1|1,m+1,end,left,right);
        return ans;
    }
    void update(int node,int add,int begin,int end,int left,int right)
    {
        if(begin>=left&&end<=right)
        {
            Node[node].sum+=(end-begin+1)*add;
            Node[node].addmark+=add;
            return;
        }
        int m=(begin+end)>>1;//小心!!
        pushdown(node,begin,end);
        if(left<=m)
            update(node<<1,add,begin,m,left,right);
        if(right>m)
            update(node<<1|1,add,m+1,end,left,right);
        pushup(node);
    }
     
    ll n,m;
     
    int main()
    {
        ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
        int i,j,k,t;
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            for(i=1; i<=n; i++) cin>>array1[i];
            buildtree(1,1,n);
            for(i=1; i<=m; i++)
            {
                int a,b,c;
                cin>>a>>b>>c;
                if(a==2) cout<<query(1,1,n,b,c)%mod*qp(2,n*m)%mod<<endl;
            }
        }
        return 0;
    }
    

      

    彼时当年少,莫负好时光。
  • 相关阅读:
    [LeetCode] 17. Letter Combinations of a Phone Number 电话号码的字母组合
    [LeetCode] 11. Container With Most Water 装最多水的容器
    [LeetCode] 42. Trapping Rain Water 收集雨水
    Meta标签中的format-detection属性及含义(转)
    html marquee 标签(转)
    css 样式引入的方法 link 与import的区别
    html meta标签使用
    backface-visibility
    zepto.js 总结
    HTTP 请求的组成 方法 已经 请求的状态码
  • 原文地址:https://www.cnblogs.com/l609929321/p/9502768.html
Copyright © 2011-2022 走看看