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 oddoutput
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
?
轉載于:https://www.cnblogs.com/Qin-Wei-Kai/p/10050604.html
總結
以上是生活随笔為你收集整理的LNSYOJ201小胖的奇偶【并查集+离散化】【做题报告】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 0xfffxxx的负数表示
- 下一篇: 数据量太大,内存不够怎么办?