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;
    }
    

      

    彼时当年少,莫负好时光。
  • 相关阅读:
    【转】网页窗口DIV自定义拖动
    【转】js获取当前日期时间“yyyy-MM-dd HH:MM:SS”
    JQuery基本知识、选择器、事件、DOM操作、动画
    LinQ高级查询、组合查询、IQueryable集合类型
    使用LinQ进行增删改查
    【转】html之file标签 --- 图片上传前预览 -- FileReader
    钢城干洗中心智能管理系统
    HTTP状态码
    HTTP报文内的HTTP信息
    HTTP协议中概念
  • 原文地址:https://www.cnblogs.com/l609929321/p/9502768.html
Copyright © 2011-2022 走看看