题面

戳这里

简要题解

做法一

因为所有数的和才100w,所以我们可以直接求出所有区间和。

直接把前缀和存到一个权值数组,再倒着存一遍,大力卷积一波。

这样做在bzoj目前还过不了,但是luogu开O2,最慢的点才500ms左右。

  1. #include<bits/stdc++.h>
  2. #define For(i,x,y) for (register int i=(x);i<=(y);i++)
  3. #define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
  4. #define cross(i,u) for (register int i=first[u];i;i=last[i])
  5. using namespace std;
  6. typedef long long ll;
  7. inline ll read(){
  8. ll x=0;int ch=getchar(),f=1;
  9. while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
  10. if (ch=='-'){f=-1;ch=getchar();}
  11. while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  12. return x*f;
  13. }
  14. const int N = 4e6+10;
  15. int m,ans,pre[N];
  16. struct node{
  17. double x,y;
  18. inline node operator + (const node &b)const{return (node){x+b.x,y+b.y};}
  19. inline node operator - (const node &b)const{return (node){x-b.x,y-b.y};}
  20. inline node operator * (const node &b)const{return (node){x*b.x-y*b.y,x*b.y+y*b.x};}
  21. }a[N],b[N];
  22. int n,l,pos[N];
  23. inline void init(){
  24. for (n=1;n<=(pre[m]<<1);n<<=1,l++);
  25. For(i,0,n-1) pos[i]=(pos[i>>1]>>1)|((i&1)<<(l-1));
  26. }
  27. const double pi = 3.1415926535897932;
  28. inline void FFT(node *a,int f){
  29. For(i,0,n-1) if (i<pos[i]) swap(a[i],a[pos[i]]);
  30. node x,y;
  31. for (register int i=1;i<n;i<<=1){
  32. node wn=(node){cos(pi/i),f*sin(pi/i)};
  33. for (register int j=0;j<n;j+=i<<1){
  34. node w=(node){1,0};
  35. for (register int k=0;k<i;k++,w=w*wn) x=a[j+k],y=w*a[j+k+i],a[j+k]=x+y,a[j+k+i]=x-y;
  36. }
  37. }
  38. if (f<0) For(i,0,n-1) a[i].x=a[i].x/n+0.5;
  39. }
  40. int main(){
  41. m=read(),a[0].x=1;
  42. For(i,1,m) pre[i]=pre[i-1]+read(),++a[pre[i]].x;
  43. For(i,0,pre[m]) b[pre[m]-i].x=a[i].x;
  44. init();FFT(a,1),FFT(b,1);
  45. For(i,0,n-1) a[i]=a[i]*b[i];
  46. FFT(a,-1);
  47. //For(i,0,n-1) printf("%d ",(int)a[i].x);puts("");
  48. For(i,0,pre[m]) if ((int)a[i].x&1) ans^=(-(i-pre[m]));
  49. printf("%d",ans);
  50. }

做法二

考虑拆位,大力分类讨论,两个树状数组维护下。

  1. #include<bits/stdc++.h>
  2. #define For(i,x,y) for (register int i=(x);i<=(y);i++)
  3. #define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
  4. #define cross(i,u) for (register int i=first[u];i;i=last[i])
  5. using namespace std;
  6. typedef long long ll;
  7. inline ll read(){
  8. ll x=0;int ch=getchar(),f=1;
  9. while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
  10. if (ch=='-'){f=-1;ch=getchar();}
  11. while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  12. return x*f;
  13. }
  14. const int N = 1e6+10;
  15. int n,cnt,Max,ans,pre[N];
  16. struct BIT{
  17. int c[N];
  18. inline void Add(int x,int y){for (;x<=pre[n];x+=x&-x) c[x]+=y;}
  19. inline int Query(int x){int ans=0;for (;x;x-=x&-x) ans+=c[x];return ans;}
  20. }t[2];
  21. int main(){
  22. n=read();
  23. For(i,1,n) pre[i]=pre[i-1]+read();
  24. for (int i=1;i<=pre[n];i<<=1){
  25. cnt=Max=0;
  26. For(j,0,n){
  27. int x=((pre[j]&i)>0),y=pre[j]&(i-1);
  28. Max=max(Max,y),cnt+=t[x^1].Query(y+1)+t[x].Query(Max+1)-t[x].Query(y+1),t[x].Add(y+1,1);
  29. }
  30. For(j,0,pre[n]) t[0].c[j]=t[1].c[j]=0;
  31. ans|=(cnt&1)*i;
  32. }
  33. printf("%d",ans);
  34. }

BZOJ4888 [Tjoi2017]异或和 FFT或树状数组+二进制拆位的更多相关文章

  1. 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分

    题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...

  2. CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组

    题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有 ...

  3. CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)

    转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interestin ...

  4. 【BZOJ】3173: [Tjoi2013]最长上升子序列(树状数组)

    [题意]给定ai,将1~n从小到大插入到第ai个数字之后,求每次插入后的LIS长度. [算法]树状数组||平衡树 [题解] 这是树状数组的一个用法:O(n log n)寻找前缀和为k的最小位置.(当数 ...

  5. 洛谷P3287 [SCOI2014]方伯伯的玉米田(树状数组)

    传送门 首先要发现,每一次选择拔高的区间都必须包含最右边的端点 为什么呢?因为如果拔高了一段区间,那么这段区间对于它的左边是更优的,对它的右边会更劣,所以我们每一次选的区间都得包含最右边的端点 我们枚 ...

  6. hdu2492树状数组

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/2492/ 题目大意:给定一个序列,求长度为三的子序列(a,b,c)使得a<b<c或a>b> ...

  7. 【BZOJ4888】[TJOI2017]异或和(树状数组)

    [BZOJ4888][TJOI2017]异或和(树状数组) 题面 BZOJ 洛谷 题解 考虑每个位置上的答案,分类讨论这一位是否存在一,值域树状数组维护即可. #include<iostream ...

  8. BZOJ4888 [Tjoi2017]异或和 【树状数组】

    题目链接 BZOJ4888 题解 要求所有连续异或和,转化为任意两个前缀和相减 要求最后的异或和,转化为求每一位\(1\)的出现次数 所以我们只需要对每一个\(i\)快速求出\(sum[i] - su ...

  9. [BZOJ4888][TJOI2017]异或和(树状数组)

    题目描述 在加里敦中学的小明最近爱上了数学竞赛,很多数学竞赛的题都是与序列的连续和相关的.所以对于一个序列,求出它们所有的连续和来说,小明觉得十分的简单.但今天小明遇到了一个序列和的难题,这个题目不仅 ...

随机推荐

  1. freeRTOS中文实用教程3--中断管理之计数信号量

    1.前言 在中断不频繁的系统中,使用二值信号量没有问题,但是中断频繁发生时,则会有中断丢失的问题. 因为中断发生时延迟任务执行,延迟任务执行的过程中,如果又来了两次中断,则只会处理第一次,第二次将会丢 ...

  2. Linux下svn常用指令【转】

    转自:http://blog.csdn.net/myarrow/article/details/8110858 Windows下的TortoiseSVN是资源管理器的一个插件,以覆盖图标表示文件状态, ...

  3. 『实践』Matlab实现Flyod求最短距离及存储最优路径

    Matlab实现Flyod求最短距离及存储最优路径 一.实际数据 已知图中所有节点的X.Y坐标. 图中的节点编号:矩阵中的编号 J01-J62:1-62; F01-F60:63-122; Z01-Z0 ...

  4. MFC 使用用指定USB设备串口

    在做设备串口通讯时,往往需要自动连接到想要连接的usb转串口设备上. #include <Setupapi.h> int CMFCApplication1Dlg::FindUSBCOM() ...

  5. C# Excel使用NPOI

    程序处理excel使用using Microsoft.Office.Interop.Excel方式,运行程序需要电脑安装excel,而且excel版本还需要一样,使用起来不方便.使用NPOI不用电脑安 ...

  6. 使用NGINX+Openresty和unixhot_waf开源防火墙实现WAF功能

    使用NGINX+Openresty实现WAF功能 一.了解WAF1.1 什么是WAF Web应用防护系统(也称:网站应用级入侵防御系统 .英文:Web Application Firewall,简称: ...

  7. 容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?【转】

    网易企业服务2017-10-13 无论是在社区,还是在同客户交流的过程中,总会被问到到底什么时候该用 Docker?什么时候用虚拟机?如果使用容器,应该使用哪个容器平台? 显而易见,我不会直接给大家一 ...

  8. 在vue-cli中引用公共过滤器filter

    在实际项目开发中,在某一组件中声明的全局过滤器Vue.filter并不能在其他组件中使用,所以,我认为只要调用两次以上或者可能会被调用两次以上的过滤器,就应该写入统一个过滤器文件中,方便统一调用.下面 ...

  9. LeetCode(28): 实现strStr()

    Easy! 题目描述: 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0 ...

  10. tomcat 拒绝服务

    一 尝试重新下载二进制安装包安装包 wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.16/bin/apache-tomcat-9.0 ...