HDU6610——Game——(待修改莫队+Nim游戏)

news/2024/11/30 8:01:15/

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6610

题目大意:

Alice和Bob在玩石子游戏,Alice选择一个区间【L,R】,确定玩游戏的区间,Bob再选择一个【l,r】,L<=l<=r<=R 

因为每次Alice可以先走,所以为了让游戏更加公平,Bob可以在每次游戏开始的时候先选择一个点pos,将pos与pos+1的石头堆

的石头数量交换。现在给你很多种操作和询问,

op==1,就会给你一个[L,R]的区间,你要回答在这个区间内有多少个l,r,Bob选择了之后Alice可以赢

op==2,表示Bob将pos和pos+1的石头进行了对换。

思路:

考虑没有任何骚操作的情况,Alice在选择了一个区间后,有多少个子区间l,r,Alice是必败的?

很显然这是一个简单的NIm游戏,只要这个子区间的异或和为0,那么Bob选择这个子区间后Alice就必败

 那么什么情况下区间的异或和为0呢?只要区间起点和终点的前缀异或和相同,那么这个区间异或和就为0

所以问题就转化为了:给你一个区间,询问这个区间中相同的数的个数有多少对?

是不是莫队模板题?没错,不过现在多了个修改操作,那就带修改莫队模板嘛,冲就完了。

离散化超时了,开了个1e6数组

#include <bits/stdc++.h>
using namespace std;/*单点修改莫队板子
*/
typedef long long ll;const int maxn=1e5+10;
const int maxm=1e6+10;
//const int maxm=1e6+10;
int a[maxn];
//询问
ll sum[maxn],p[maxn],block;//分块,带修改的分块最好为2/3
struct Query{int l,r;int id;int t;//时间轴,因为有修改操作Query(int _l,int _r,int _id,int _t):l(_l),r(_r),id(_id),t(_t){}Query(){}
}q[maxn];
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[maxn];//答案
ll ans;
ll bar[maxm];//区间不同的数
/*
离散化超时了。。。
vector<ll>v;//离散化
int getid(int cur){return lower_bound(v.begin(),v.end(),cur)-v.begin()+1;
}
*///莫队加减模板
void add(int pos){ans+=bar[sum[pos]];bar[sum[pos]]++;
}
void del(int pos){ans-=--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]);}
}
signed main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){//v.clear();for(int i=0;i<maxn;i++)bar[i]=0;block=max(1ll*10,(ll)pow(n,2.0/3));sum[0]=0;for(int i=1;i<=n;i++){scanf("%d",&a[i]);sum[i]=sum[i-1]^a[i];//v.push_back(sum[i]);}int qcnt=0,kcnt=0;//sort(v.begin(),v.end());// v.erase(unique(v.begin(),v.end()),v.end());while(m--){int op;scanf("%d",&op);if(op==1){int l,r;scanf("%d%d",&l,&r);q[++qcnt]=Query(l-1,r,qcnt,kcnt);//kcnt用来表示时间,以修改操作改变时间}else{int t;scanf("%d",&t);p[++kcnt]=t;}}sort(q+1,q+qcnt+1,cmp);int dexl=1,dexr=0,tt=0;ans=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-ans;}for(int i=1;i<=qcnt;i++){printf("%lld\n",ANS[i]);}}return 0;
}

 


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

相关文章

HDU 6610 Game — 2019第三场杭电多校 1008题

目录 题意思路AC_Code (hdu 6610) 题意 大概说一下我理解的题意。。。 链接&#xff1a;here 你有\(n\)堆石子&#xff0c;每堆石子有\(a_i\)个石子。游戏规则&#xff1a;\(Alice\)先选择一个大范围\([L,R]\)区间内的石子&#xff0c;\(Bob\)选择一个子区间\([l,r]\)内的石子最…

HDU - 6610 Game (带修莫队)

题链&#xff1a;https://vjudge.net/problem/HDU-6610 题意&#xff1a;用到了尼姆博弈的结论。对于一个区间[L,R]&#xff0c;问有多少子区间[l,r],a[l] ^ a[l1] ^ a[l2] ^ ... ^ a[r] &#xff01; 0 &#xff1f; 有修改&#xff0c;修改是将a[pos],a[pos1]交换。 思路…

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

题目 题意&#xff1a; 给你n堆石头&#xff0c;m次操作。操作&#xff1a;将x与x1堆石头交换位置 询问:[L,R]多少子区间里面的石头值异或起来不等于0. 思路&#xff1a; 带修莫队板子。那我们就求异或起来等于0的子区间个数。可能modify_t add del函数有一丢丢不好写! &#…

带修莫队学习笔记+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;所有数…