LNSYOJ201小胖的奇偶并查集+离散化做题报告
Posted qin-wei-kai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LNSYOJ201小胖的奇偶并查集+离散化做题报告相关的知识,希望对你有一定的参考价值。
这道题是一个带权并查集
题目描述
huyichen和xuzhenyi在玩一个游戏:他写一个由0和1组成的序列。 huyichen选其中的一段(比如第3位到第5位),问他这段里面有奇数个1 还是偶数个1。xuzhenyi回答你的问题,然后huyichen继续问。 xuzhenyi有可能在撒谎。huyichen要检查xuzhenyi的答案,指出在xuzhenyi的第几个回答一定有问题。 有问题的意思就是存在一个01序列满足这个回答前的所有回答,而且不存在序列 满足这个回答前的所有回答及这个回答。
输入格式
第1行一个整数,是这个01序列的长度(≤1000000000)(≤1000000000) 第2行一个整数,是问题和答案的个数(≤5000)(≤5000)。 第3行开始是问题和答案, 每行先有两个整数,表示你询问的段的开始位置和结束位置。 然后是xuzhenyi的回答。odd表示有奇数个1,even表示有偶数个
输出格式
输出一行,一个数X,表示存在一个01序列满足第1到第X个回答, 但是不存在序列满足第1到第X+1个回答。如果所有回答都没问题,你就输出 所有回答的个数。
样例一
input
10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
output
3
限制与约定
时间限制:1s
空间限制:256MB
思路还是比较好想的,0代表偶数个,1代表奇数个
本题关键是理解
l r even 等价于0-l-1与0-R的序列奇偶性相同。odd等价于奇偶性相反
合并方式和食物链,关押罪犯很像;
这道题有一个很重要的东西是离散化
网上的代码是
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 const int N=1e5+7; 6 int t[N],a[N],n,m; 7 int main() 8 { 9 cin>>n; 10 for(int i=1;i<=n;i++) 11 cin>>a[i],t[i]=a[i]; 12 sort(t+1,t+n+1); 13 m=unique(t+1,t+n+1)-t-1; 14 for(int i=1;i<=n;i++) 15 a[i]=lower_bound(t+1,t+m+1,a[i])-t; 16 for(int i=1;i<=n;i++)cout<<a[i]<<" "; 17 }
这个一定要记住!!(unique是去重函数)
还有一种就是用结构体,也是我这道题用的,先记录一个数据的位置,排完序之后再将它是第几大赋回去;
针对具体情况还要进行改动,比如本题进行了题号的记录和排序,要灵活处理!
注意:
1.要用l-1来查询和修改,网上有读的时候就- -的,也可以
2.用结构体离散化,要注意相同数的处理(见35-41行)
3.最后记得要输出最后一个号码,我就是忘了,导致了好多个EOF
AC代码在此
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 struct node{ 5 int data,no,op,hs; 6 }nd[5100*2];//0:l,1:r; 7 int n,k,f[5100*2],val[5100*2]; 8 char opt[5100][51]; 9 int find(int x) 10 { 11 if(f[x]==x)return x; 12 int ff=find(f[x]); 13 val[x]=(val[x]+val[f[x]])%2; 14 return f[x]=ff; 15 } 16 bool cmp1(node a,node b) 17 {return a.data<b.data;} 18 bool cmp2(node a,node b) 19 {return a.no<b.no;} 20 int main() 21 { 22 scanf("%d%d",&n,&k); 23 for(int i=1;i<=k;i++) 24 { 25 scanf("%d",&nd[i].data); 26 nd[i].no=i; 27 nd[i].op=0; 28 nd[i].data; 29 scanf("%d",&nd[i+k].data); 30 nd[i+k].no=i; 31 nd[i+k].op=1; 32 scanf("%s",opt[i]); 33 } 34 sort(nd+1,nd+2*k+1,cmp1); 35 int tt=0; 36 for(int i=1;i<=2*k;i++) 37 { 38 if(nd[i].data==nd[i-1].data)nd[i].hs=tt; 39 else nd[i].hs=++tt; 40 f[tt]=tt; 41 } 42 sort(nd+1,nd+2*k+1,cmp2); 43 int cnt=0; 44 for(int i=1;i<=2*k;i+=2) 45 { 46 cnt++; 47 int l,r; 48 for(int j=i;j<=i+1;j++) 49 { 50 if(nd[j].op==1)r=nd[j].hs; 51 else l=nd[j].hs; 52 } 53 int fx=find(l-1),fy=find(r); 54 if(opt[cnt][0]==‘e‘) 55 { 56 if(fx!=fy) 57 { 58 val[fy]=(val[l-1]+val[r])%2; 59 f[fy]=fx; 60 }else 61 { 62 if(val[l-1]!=val[r]) 63 { 64 printf("%d",nd[i].no-1); 65 return 0; 66 } 67 } 68 }else if(opt[cnt][0]==‘o‘) 69 { 70 if(fx!=fy) 71 { 72 val[fy]=(val[l-1]+val[r]+1)%2; 73 f[fy]=fx; 74 }else 75 { 76 if(val[l-1]==val[r]) 77 { 78 printf("%d",nd[i].no-1); 79 return 0; 80 } 81 } 82 } 83 } 84 printf("%d",k); 85 return 0; 86 }
By 浅夜_MISAKI
以上是关于LNSYOJ201小胖的奇偶并查集+离散化做题报告的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 4195: [Noi2015]程序自动分析 [并查集 离散化 | 种类并查集WA]
Codeforces Round #396 (Div. 2) D题Mahmoud and a Dictionary(并查集)解题报告