摘要:一:#include<iostream>#include<cstdio>#include<cmath>#include<cstring>using namespace std;#define MAXN 150#define inf 99999999double map[MAXN][MAXN],x[MAXN],y[MAXN],dis[MAXN];int mark[MAXN];double prime (int n){ int i,j,min,now=0; double ans=0; memset(mark,0,sizeof(mark)); for(
阅读全文
摘要:#include<iostream>#include<cstdio>#include<queue>#include<vector>using namespace std;#define MAXN 105int n,k;struct B{ int end,len,toll; friend bool operator<(B x,B y) { if(x.len!=y.len) return x.len>y.len; return x.toll>y.toll; }};vector<B> v[MAXN];priority_qu
阅读全文
摘要:#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>using namespace std;#define MAXN 30010int father[MAXN],rank[MAXN];int num[MAXN]; //根节点x记录集合的数量void make_set(int x){ father[x]=x; num[x]=1;//初始化每个根节点x的数量为1}int find_set(int x){ if(x==fathe
阅读全文
摘要:#include<cstdio>#include<iostream>using namespace std;#define MAXN 30010int father[MAXN];int rank[MAXN];void make_set(int x){ father[x]=x; rank[x]=0;}int find_set(int x){ int t; if(x==father[x]) return x; else { t=father[x]; father[x]=find_set(father[x]); return father[x]; }}void union_s
阅读全文
摘要:#include<cstdio>#include<iostream>using namespace std;#define MAXN 2010int father[MAXN];int rank[MAXN];void make_set(int x){ father[x]=x; rank[x]=0;}int find_set(int x){ int t; if(x==father[x]) return x; else { t=father[x]; father[x]=find_set(father[x]); rank[x]=(rank[x]+rank[t])%2; retu
阅读全文
摘要:#include<cstdio>#include<iostream>using namespace std;#define MAXN 1000int father[MAXN];int rank[MAXN];int a[MAXN],b[MAXN];void make_set(int x){ father[x]=x; rank[x]=0;}int find_set(int x){ if(x==father[x]) return x; return father[x]=find_set(father[x]);}void union_set(int x,int y){ int
阅读全文
摘要:Description动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。有人用两种说法对这N个动物所构成的食物链关系进行描述:第一种说法是"1 X Y",表示X和Y是同类。第二种说法是"2 X Y",表示X吃Y。此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。1) 当前的话与前面的某些真的话冲突,就是假话;2) 当前的话中X
阅读全文
摘要:题意:求QuickSort最坏情况下的交换次数。理解以后知道应该是一个求序列的逆序对问题。#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define max 1000001long long tree[max];long long x[max];long long getsum(long long idx){ long long sum=0; while(idx>0) { sum+=tree[idx]; idx-=(idx&-idx); } ret
阅读全文
摘要:#include<iostream>#include<cstdio>using namespace std;#define max 32001#define N 15001int tree[max];int level[N];int getsum(int idx){ int sum=0; while(idx>0) { sum+=tree[idx]; idx-=(idx&-idx); } return sum;}void addval(int idx,int val){ while(idx<=max) { tree[idx]+=val; idx+=(i
阅读全文
摘要:第一次建树时,根节点cover域为1。以后要涂色的时候,先看涂色区域是否覆盖当前节点的范围,如果覆盖,直接更改当前节点的cover域。否则,先看当前节点是否为纯色,如果是纯色,就要把纯色信息传递给左右子树,而当前节点cover域则变为0.表明当前节点覆盖的颜色不在是纯色,这样照着这个思路递归更新子节点的cover域。查询就比较简单了,中间用一个数组来表示哪些颜色已经上色。#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define MAXN 100010#defi
阅读全文
摘要:题目的难点是怎样保存Dij这条信息。本质上就是把两个集合并起来,一个集合是现在已经知道的跟i相关的罪犯,另外一集合是现知的跟j相关的罪犯,当然这两个集合有可能是同一个集合(此时i,j之间的关系在此信息之前就已经确定了)。这样所有的罪犯分成若干个集合,每个罪犯属于且仅属于一个集合。对于每条信息Dij,我们都把包含i的集合和包含j的集合并成一个集合。我们采取森林的方法来保存这些集合。对于属于同一颗树的所有节点,划分一个集合。这样两个集合之间的并就简化为了两棵树之间的合并了。为了查询i所在的树,不断查找其父节点,最后找到i所在树的头节点即可。i,j在同一颗树上的充分必要条件就是他们的头节点一样。而D
阅读全文