zoukankan      html  css  js  c++  java
  • poj1733 parity game---离散化+带权并查集

    题目链接:https://vjudge.net/problem/POJ-1733

    题意:给定一个01序列,对于每个给出的区间,回答一个区间内1的个数为奇数还是偶数。求在第几条回答时出现矛盾

    设v[x]=0/1表示x与par[x]组成的区间有偶数/奇数个1,之后利用异或的性质使用带权并查集即可,具体就是加减的奇偶性和异或相对应(由此可发现只能设v[x]=0表示偶数)。序列可能很长,但是询问只有5000个,所以需要离散化,这儿偷懒用了map。另外还有一个小技巧之前用过,就是将左边区间变成开区间,这个在hdu3038中也用到了

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<map>
    using namespace std;
    
    const int maxn=10000;
    int t,n,q,i,cnt,f,ans;
    int par[maxn+10],v[maxn+10];
    map<int,int> c;
    
    int find(int x){
    	if (par[x]!=x){
    	  int u=par[x];
    	  par[x]=find(par[x]);
    	  v[x]^=v[u]; //*	  
    	}
    	return par[x];
    }
    
    int main(){
    	std::ios::sync_with_stdio(false);
    	cin>>n>>q; f=0;
    	for (i=1;i<=maxn;i++) par[i]=i;
    	for (i=1;i<=q;i++){
    	  int a,b; string s;
    	  cin>>a>>b; cin>>s;
    	  if (a>b) swap(a,b); //*
    	  if (c[a-1]==0) c[a-1]=(++cnt); if (c[b]==0) c[b]=(++cnt); //离散化  
    	  int fa=find(c[a-1]); int fb=find(c[b]);
    	  if (fa==fb){
    	  	int t=v[c[a-1]]^v[c[b]]; //*
    	  	if (((t==0&&s=="odd")||(t==1&&s=="even"))&&f==0) {
    	  	  f=1; ans=i-1;
    		}
    	  }
    	  else{
    	  	int t=(s=="odd")?1:0;
    	  	par[fa]=fb; v[fa]=t^v[c[a-1]]^v[c[b]]; //*
    	  }
    	}
    	if (f==0) cout<<q<<endl; else cout<<ans<<endl; 
    	return 0;
    }
    

      

  • 相关阅读:
    Java基础知识:正则表达式
    NodeJs 中 将表单数据转发到后台
    单片机的远程升级
    一些开源协议
    物联网的一些例子
    python一些开源特色库
    qt练习
    网页编程学习笔记
    PCB相关
    工业控制系统
  • 原文地址:https://www.cnblogs.com/edmunds/p/13449885.html
Copyright © 2011-2022 走看看