[luogu3760 TJOI2017] 异或和(树状数组)

传送门

Solution

一位一位考虑,直接得到答案中第i为是否为1

Code

//By Menteur_Hxy
#include <ctime>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Re register
#define Ms(a,b) memset(a,(b),sizeof(a))
#define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
#define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
#define Lof(i,a,b) for(Re int i=(a),_=(b);i<=_;i+=i&-i)
#define Lor(i,a) for(Re int i=(a);i;i-=i&-i)
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    return x*f;
}

const int N=1e6+10;
int n,m;
LL ans;
LL a[N],s[N],b[N];

struct BIT{
    int da[2][N];
    void clear() {Ms(da,0);}
    void Modify(int x,int k) {Lof(i,x,m)da[k][i]++;}
    LL query(int x,int k) {LL t=0;Lor(i,x)t+=da[k][i];return t;}
}B;

int main() {
    n=read(); Fo(i,1,n) a[i]=read(),s[i]=s[i-1]+a[i]; m=s[n];
    Fo(i,0,20) {
        if((1ll<<i)>m) break;
        bool cnt=0; B.clear(); B.Modify(1,0);
        Fo(j,1,n) {
            LL o=s[j]&(1ll<<i),tmp=0;
            if(o) tmp=B.query(b[j]+1,0)+B.query(m,1)-B.query(b[j]+1,1);
            else tmp=B.query(b[j]+1,1)+B.query(m,0)-B.query(b[j]+1,0);
            if(tmp&1) cnt^=1;  B.Modify(b[j]+1,(o>0)); b[j]|=o;
        }
        if(cnt) ans|=(1ll<<i);
    }
    printf("%lld",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9807624.html

时间: 2024-10-13 20:32:46

[luogu3760 TJOI2017] 异或和(树状数组)的相关文章

2018年四校联合周赛-第二场 B.异或和问题(二维树状数组)

异或和问题 TimeLimit:1000MS  MemoryLimit:256MB 64-bit integer IO format:%I64d Problem Description 现在有一个n行n列的矩阵.初始状态下,矩阵里的所有值都为0.行的编码是从1到n,列的编码也同样是从1到n. ai,?j.是在第i行第j列的数.子矩阵(x0, y0, x1, y1)是由ai,?j. (x0?≤?i?≤?x1, y0?≤?j?≤?y1)组成的矩阵. 现在需要进行下列的两个操作:       1.查询

[P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)

题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生 这两本书页数的和的厌烦度.现在有n本被打乱顺序的书,在接下来m天中每天都会因为读者的阅览导致书籍顺序改变位置.因为小豆被要求在接下来的m天中至少 要整理一次图书.小豆想知道,如果他前i天不去整理,第i天他的厌烦度是多少,这样他好选择厌烦度最小的那天去整理. 输入输出格式 输入格式: 第一行会有两个数,n,m分别表示有n本书,m天 接下来n行,每行两

Codeforces 570D TREE REQUESTS dfs序+树状数组 异或

http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Roman planted a tree consisting of?n?vertices. Each vertex contains a lowercase

【二维树状数组】See you~

https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/F [题意] 给定一个矩阵,每个格子的初始值为1.现在可以对矩阵有四种操作: A x y n1 :给格点(x,y)的值加n1 D x y n1: 给格点(x,y)的值减n1,如果现在格点的值不够n1,把格点置0 M x1 y1 x2 y2:(x1,y1)移动给(x2,y2)n1个 S x1 y1 x2 y2 查询子矩阵的和 [思路] 当然是二维树状数组 但是一定要注意:lowbi

[luogu P3801] 红色的幻想乡 [线段树][树状数组]

题目背景 蕾米莉亚的红雾异变失败后,很不甘心. 题目描述 经过上次失败后,蕾米莉亚决定再次发动红雾异变,但为了防止被灵梦退治,她决定将红雾以奇怪的阵势释放. 我们将幻想乡看做是一个n*m的方格地区,一开始没有任何一个地区被红雾遮盖.蕾米莉亚每次站在某一个地区上,向东南西北四个方向各发出一条无限长的红雾,可以影响到整行/整列,但不会影响到她所站的那个地区.如果两阵红雾碰撞,则会因为密度过大而沉降消失.灵梦察觉到了这次异变,决定去解决它.但在解决之前,灵梦想要了解一片范围红雾的密度.可以简述为两种操

HDU 5465 Clarke and puzzle Nim游戏+二维树状数组

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle Accepts: 42 Submissions: 269 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 克拉克是一名人格分裂患者.某一天,有两个克拉克(aa和bb)在玩一个方格游戏. 这个方格是一个n*mn∗m的矩阵,每个格子里有一

codeforces 703D D. Mishka and Interesting sum(树状数组)

题目链接: D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes input standard input output standard output Little Mishka enjoys programming. Since her birthday has just passed, her friends decided to present h

【手动开栈】【dfs序】【树状数组】【Tarjan】bzoj2819 Nim

考虑树状数组区间修改(只对其子树的答案有影响)点查询,每个点记录的是它到根路径上的权值异或和. 答案时query(L)^query(R)^a[lca]. 这种方法在支持区间加法.减法的树上询问的时候可以避免树链剖分. 可能爆栈,考虑手动开栈.(诶诶Tarjan预处理lca的时候怎么没手动开栈?不要在意^_^) 实际上不会爆的. #include<cstdio> #include<stack> #include<algorithm> #include<queue&g

HDU 3854 Glorious Array(树状数组)

题意:给一些结点,每个结点是黑色或白色,并有一个权值.定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大.给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前距离小于K的结点有多少对,K是一个定值. 思路:先求最初时候小于k的结点有多少对,然后每次改变颜色的时候,统计该点左侧和右侧各有多少同色和异色的结点(这一步使用树状数组),分别处理就行.另外需要预处理离某个结点最近的两个距离小于K的结点的位置. 代码写的略乱. #include<cstdio> #