HDU6610(Game 带修莫队+将区间内的值异或转化为两个前缀异或)

news/2024/11/30 7:58:14/

题目
在这里插入图片描述
题意: 给你n堆石头,m次操作。操作:将x与x+1堆石头交换位置 询问:[L,R]多少子区间里面的石头值异或起来不等于0.
思路: 带修莫队板子。那我们就求异或起来等于0的子区间个数。可能modify_t add del函数有一丢丢不好写! ?! 我们利用前缀异或和。若区间[l,r]满足要求则sum[r]^sum[l-1]=0,即sum[r]=sum[l-1]。所以这个题我们就转化为了区间内有多少对相同的数嘻嘻。需要注意的是每次查询区间[L,R]时 我们应变成[L-1,R]。因为sum[r]=sum[l-1]这句话。再者需要注意的是,这个题好像子区间不能只取一堆(假如真的只取1堆 只能这堆为0 相当于没取) 。 对于时间tt的移动应该放在dexl,dexr移动之后!!再者block=pow(n,2.0/3) sqrt直接T。
emmm还有交换x x+1堆,x+1堆的sum[x+1]是不会变的。modify_t是只需要修改x+1的。这次撤回修改与添加修改都是同一个一样的函数。因为撤销修改也是x与x+1再交换回来。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define en '\n'
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
const int N=1e5+5,M=1e6+5;
int a[N],sum[N],p[N],block;
struct Query{int l,r,id,t;}q[N];
int cmp(Query x,Query y){if(x.l/block!=y.l/block) return x.l/block<y.l/block;if(x.r/block!=y.r/block) return x.r/block<y.r/block;return x.t<y.t;
}
ll ans[N],res;
ll bar[M];//桶
void add(int pos) {res+=bar[sum[pos]]++;}
void del(int pos) {res-=--bar[sum[pos]];}
void modify_t(int i,int t){int flag=q[i].l<=p[t]&&p[t]<=q[i].r;if(flag) del(p[t]);sum[p[t]]^=a[p[t]],swap(a[p[t]],a[p[t]+1]),sum[p[t]]^=a[p[t]];if(flag) add(p[t]);
}
int main(){int n,m;while(~scanf("%d%d",&n,&m)){m(bar,0);//block=sqrt(n);block=max(10,(int)pow(n,2./3));for(int i=1;i<=n;++i) scanf("%d",&a[i]),sum[i]=sum[i-1]^a[i];int qcnt=0,kcnt=0;while(m--){int op,x,l,r;scanf("%d",&op);if(op==1) scanf("%d%d",&l,&r),q[++qcnt]=(Query){l-1,r,qcnt,kcnt};//注意是l-1else scanf("%d",&x),p[++kcnt]=x;}sort(q+1,q+qcnt+1,cmp);int dexl=1,dexr=0,tt=0;res=0;for(int i=1;i<=qcnt;++i){while(dexr<q[i].r) add(++dexr);while(dexl>q[i].l) add(--dexl);while(dexr>q[i].r) del(dexr--);while(dexl<q[i].l) del(dexl++);while(tt<q[i].t) modify_t(i,++tt);while(tt>q[i].t) modify_t(i,tt--);ans[q[i].id]=(ll)(q[i].r-q[i].l)*(q[i].r-q[i].l+1)/2-res;}for(int i=1;i<=qcnt;++i) printf("%lld\n",ans[i]);}
}

http://www.ppmy.cn/news/636549.html

相关文章

带修莫队学习笔记+HDU6610

带修莫队 允许离线的带区间修改的操作 -将修改操作编号&#xff0c;称为"时间戳" 普通莫队是不能带修改的&#xff0c;我们可以强行让它可以修改 可以强行加上一维时间维, 表示这次操作的时间 [ l − 1 , r , t i m e ] [l−1, r, time] [l−1,r,time] [ l 1 , r …

Qt笔记-自定义QSet,QHash的Key

官方文档已经说得很详细了。 If you want to use other types as the key, make sure that you provide operator() and a qHash() implementation. Example:#ifndef EMPLOYEE_H#define EMPLOYEE_Hclass Employee{public:Employee() {}Employee(const QString &name, con…

UPC 6610 Restoring Road Network

问题 C: Restoring Road Network 题目描述 In Takahashi Kingdom, which once existed, there are N cities, and some pairs of cities are connected bidirectionally by roads. The following are known about the road network: People traveled between cities only thr…

【HDU 6610】Game

1.题目链接。题目的意思其实就是在问&#xff1a;先把数列做一个前缀异或和&#xff0c;然后给定区间【L,R】&#xff0c;算一下区间内有多少对数异或值不为0.我们知道&#xff0c;只有两个相等的数异或起来才是0&#xff0c;所以再转化计算其对立问题&#xff1a;区间内有多少…

2019杭电多校第三场 HDU 6610

题意 给出 n n n个数&#xff0c;询问一个区间 [ L , R ] [L,R] [L,R]&#xff0c;在这个区间内找 [ l , r ] [l,r] [l,r] 做 N I M NIM NIM游戏&#xff0c;问先手必胜的 [ l , r ] [l,r] [l,r] 种类数 首先&#xff0c; N I M NIM NIM游戏的判断条件为 &#xff0c;所有数…

TPS61088的同步升压转换器 替换物料 SGM6610

圣邦微电子的SGM6610是一款输出高达10A的开关型同步升压芯片&#xff0c;其输入电压范围&#xff0c;输出电压范围&#xff0c;工作模式&#xff0c;开关频率范围&#xff0c;拓扑结构&#xff0c;结温范围与TI公司的TPS61088相同&#xff0c;封装尺寸和引脚位号定义也与TI公司…

hdu 6610 Game

题意&#xff1a;带修改地维护区间异或和 思路&#xff1a;带修改莫队&#xff08;注意分块大小为 0.66666n&#xff09; #include <bits/stdc.h> using namespace std; typedef int lint; typedef long long LL; const lint maxn 1000005; lint a[maxn],pos[maxn],su…

新品、实测、终端……MWC2023上海展,移远通信又为物联行业带来了哪些惊喜?

6月28日&#xff0c;MWC上海世界移动通信大会拉开帷幕&#xff0c;围绕“时不我待”主题&#xff0c;今年的展会包含5G变革、数字万物与“超越现实”三大主题方向&#xff0c;充分展示了以5G、大数据、AI等新一代信息技术赋能社会经济发展的重要成果。 作为物联网整体解决方案供…