• 魔卡少女(cardcaptor)——线段树


    题目

    【题目描述】

    君君是中山大学的四年级学生。有一天在家不小心开启了放置在爸爸书房中的一本古书。于是,君君把放在书中最上面的一张牌拿出来观摩了一下,突然掀起一阵大风把书中的其她所有牌吹散到各地。这时一只看上去四不像的可爱生物「封印之兽」可鲁贝洛斯从书中钻了出来,它告诉君君书中的牌叫「库洛牌」,现在散落各地已实体化,要君君将它们全部再次封印起来,以免危害世界,于是君君开始过上了收服「库洛牌」的旅程。

    经过不懈努力,君君集齐了 $N$ 张库洛牌,最后的审判就要来临,为了战胜审判者月,君君开始研究起这 $N$ 张库洛牌的魔法效果。君君已经将 $N$ 张库洛牌从左到右依次排列好,这 $N$ 张库洛牌的魔法值从左到右依次为 $a_1, a_2, a_3,…,a_N$ 。她将告诉你这 $N$ 张库洛牌的魔法值。在最后的审判时,审判者月将会选择一个区间进行 PK,君君预测了可能进行 PK 的若干区间,她想请你帮助她计算这些区间的魔法效果,以便她更好地布置战术。一个区间内,所有连续子序列都会产生魔法效果。一个连续子序列 $p_1, p_2, p_3,…,p_k$ 的魔法效果定义为 $p_1⊕p_2⊕p_3⊕…⊕p_k$ ($⊕$ 表示异或)。一个区间的魔法效果定义为所有连续子序列的魔法效果的和。例如有 $5$ 张库洛牌,魔法值为 $1, 1, 2, 4, 5$,询问区间 $[2, 4]$ 的魔法效果。区间 $[2, 4]$ 包含的连续子序列为 ${1}, {2},{4}, {1,2}, {2,4}, {1,2,4}$, 它们的魔法值分别为 $1,2,4,3,6,7$,所以区间 $[2,4]$ 的魔法效果为 $1 + 2 + 4 + 3 + 6 + 7 = 23$。

    库洛牌的魔法效果狂拽炫酷吊炸天,这个值可能很大,所以你只需要输出这个值模 $100000007$。另外,任性的君君可以在询问的过程中对库洛牌的魔法值进行修改。

    现在,君君给出了 $M$ 个操作,操作格式如下:

    1. `M p x` 表示将第 $p$ 张库洛牌的魔法值修改为 $x$。

    2. `Q l r` 表示询问区间 $[l,r]$ 的魔法效果。

    Pascal 语言中,异或操作符为 xor,C++ 语言中,异或操作符为^。

    【输入格式】

    第一行为一个整数 $N$,表示有 $N$ 张库洛牌。

    第二行为 $N$ 个整数,表示一开始 $N$ 张库洛牌的值。

    第三行为一个整数 $M$,表示有 $M$ 个操作。

    接下来 $M$ 行,每行表示一个操作,格式如题目描述所示。

    【输出格式】

    对于每个操作 $2$,输出一行,每行一个数,表示询问的区间 $[l,r]$ 的魔法效果模 $100000007$。

    【样例输入】

    5
    1 2 3 4 5
    7
    Q 1 3
    M 2 7
    Q 1 3
    M 2 2
    Q 1 3
    M 4 2
    Q 1 5

    【样例输出】

    10
    26
    10
    47

    【数据范围与提示】

    $30\%$ 的数据,$N,M≤300$。

    另外 $20\%$ 的数据,$N,Mle 30000$,操作 $1$ 的数量不超过 $50$。

    $80\%$ 的数据,$N,M≤30000$。

    $100\%$ 的数据,$N≤100000,M≤100000,0≤a_i,x≤1000$。

    题解

    看到 $ a_i leq 1000 $,就感觉到有玄机

    做前缀异或和 $ sum $,区间 $ [l_i,r_i] $ 的答案即为 $sum[r_i] xor sum[l_i-1] $,可以发现,每一位的异或值互不影响,并且第 $i$ 位要为 $ 1 $ 必须满足一个为 $ 0 $ 一个为 $ 1 $,所以这一段区间这个位贡献就是 区间内 $ 0 $ 的个数 $ imes 1$ 的个数

    维护区间信息,自然是线段树

    开 $10$ 课线段树,模拟维护前缀异或和,存下每一位的 $ 0,1 $ 个数,直接查询即可

    考虑维护,修改 $ x $ 为 $y$ 即为将 $ [x,n] xor (x_{las} xor y) $

    然后忘记判断子节点的 $tag$ 调得心态爆炸

    代码

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define _(d) while(d(isdigit(ch=getchar())))
     4 using namespace std;
     5 int R(){
     6     int x;bool f=1;char ch;_(!)if(ch=='-')f=0;x=ch^48;
     7     _()x=(x<<3)+(x<<1)+(ch^48);return f?x:-x;}
     8 const int N=1e5+5,P=1e8+7;
     9 int n,m,a[N],sum[N],tag[N<<2];
    10 char ch[10];
    11 struct seg{int num[2][12];}tr[N<<2];
    12 #define Ls rt<<1
    13 #define Rs rt<<1|1
    14 seg make(seg a,seg b){
    15     seg c;
    16     for(int i=0;i<=10;i++){
    17         c.num[0][i]=a.num[0][i]+b.num[0][i];
    18         c.num[1][i]=a.num[1][i]+b.num[1][i];
    19     }
    20     return c;
    21 }
    22 void build(int rt,int l,int r){
    23     if(l==r){
    24         for(int i=0;i<=10;i++)
    25             tr[rt].num[(sum[l]>>i)&1][i]=1;
    26         return;}
    27     int mid=(l+r)>>1;
    28     build(Ls,l,mid),build(Rs,mid+1,r);
    29     tr[rt]=make(tr[Ls],tr[Rs]);
    30     return;
    31 }
    32 void push(int rt){
    33     int x=tag[rt];tag[rt]=0;
    34     for(int i=0;i<=10;i++)
    35         if((x>>i)&1)
    36             swap(tr[rt].num[0][i],tr[rt].num[1][i]);
    37     tag[Ls]^=x,tag[Rs]^=x;
    38     return;
    39 }
    40 seg query(int rt,int l,int r,int ql,int qr){
    41     if(tag[rt])push(rt);
    42     if(ql<=l&&qr>=r)return tr[rt];
    43     int mid=(l+r)>>1;
    44     if(mid>=qr)return query(Ls,l,mid,ql,qr);
    45     if(mid<ql)return query(Rs,mid+1,r,ql,qr);
    46     return make(query(Ls,l,mid,ql,qr),query(Rs,mid+1,r,ql,qr));
    47 }
    48 LL get(seg a){
    49     LL res=0;
    50     for(int i=0;i<=10;i++)
    51         res=(LL)(res+(1ll<<i)*a.num[0][i]*a.num[1][i]%P)%P;
    52     return res;
    53 }
    54 void update(int rt,int l,int r,int k,int x){
    55     if(k<=l){
    56         tag[rt]^=x,push(rt);
    57         return;}
    58     int mid=(l+r)>>1;
    59     if(tag[Ls])push(Ls);
    60     if(tag[Rs])push(Rs); 
    61     if(k<=mid)update(Ls,l,mid,k,x);
    62     update(Rs,mid+1,r,k,x);
    63     tr[rt]=make(tr[Ls],tr[Rs]);
    64     return;
    65 }
    66 int main(){
    67     n=R();
    68     for(int i=1;i<=n;i++)
    69         a[i]=R(),sum[i]=sum[i-1]^a[i];
    70     build(1,0,n);
    71     m=R();
    72     for(int i=1,x,y;i<=m;i++){
    73         scanf("%s",ch+1),x=R(),y=R();
    74         if(ch[1]=='Q')printf("%lld
    ",get(query(1,0,n,x-1,y)));
    75         else
    76             update(1,0,n,x,a[x]^y),a[x]=y;
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    线上查询及帮助命令:
    windows: 2.7 3.5 (主要)
    get the execution time of a sql statement.
    java-kafka安装以及使用案例
    java-黑马头条 weex前端路由
    MYSQL安装
    缓存
    Flask中current_app和g对象
    [ValueError: signal only works in main thread]
    Flask-SQLAlchemy操作
  • 原文地址:https://www.cnblogs.com/chmwt/p/10604069.html
Copyright © 2020-2023  润新知