//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
B 742B Arpa’s obvious problem and Mehrdad’s terrible solution
题意:给出n个数和x,求满足 1 ≤ i < j ≤ n 并且 的数有几对
题解:如果a[i]^a[j]=x,那么a[i]^x=a[j]。
坑点:亦或要开两倍空间。(太坑了沃日)
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define de(x) cout << #x << "=" << x << endl
const int N=1000005;
int a[N],b[N];
int main() {
int n,x;
while(~scanf("%d%d",&n,&x)) {
memset(b,0,sizeof(b));
for(int i=1;i<=n;++i) {
scanf("%d",&a[i]);
++b[a[i]];
}
ll ans=0;
for(int i=1;i<=n;++i) {
--b[a[i]];
ans+=0ll+b[a[i]^x];
}
printf("%I64d\n",ans);
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C 741A Arpa's loud Owf and Mehrdad's evil plan
题意:数组a表示i到a[i]有一条有向边,找一个最小的k,使得从x出发走k步能到达y,并且从y出发走k步能到达x。无解输出-1
题解:有解的情况肯定是:图由一个一个圈组成的。那么我们处理出所有圈的大小,偶数圈要除2。最后答案就是所有圈的值的lcm
注意:不标记vis的写法会爆ll
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define de(x) cout << #x << "=" << x << endl
const int N=105;
int a[N],vis[N],b[N];
int gcd(int a,int b) {
if(b==0) return a;
return gcd(b,a%b);
}
int lcm(int a,int b) {
return a*b/gcd(a,b);
}
int main() {
int n;
while(~scanf("%d",&n)) {
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
int m=0;
int flag=1;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n&&flag;++i) {
if(vis[i]) continue;
int t=0,p=i;
for(;;) {
vis[p]=1;
p=a[p];
++t;
if(p==i) break;
if(vis[p]) {
flag=0;
break;
}
}
if(t%2==0) t/=2;
b[++m]=t;
}
if(flag) {
int ans=1;
for(int i=1;i<=m;++i) ans=lcm(ans,b[i]);
printf("%d\n",ans);
} else {
puts("-1");
}
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
题意:n个物品,m个关系,总空间v。每个物品有花费w和价值b。m个关系类似于并查集的朋友关系。选取物品的规则是:对于一个关系圈,要么不选,要么只选一个,要么全选,求最大价值。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define de(x) cout << #x << "=" << x << endl
const int N=1005;
int w[N],b[N],mp[N][N],d[N],vis[N],a[N];
int num,n,m,v,sumw,sumb;
void dfs(int u) {
vis[u]=1;
a[++num]=u;
sumw+=w[u];
sumb+=b[u];
for(int i=1;i<=n;++i) {
if(mp[u][i]&&!vis[i]) dfs(i);
}
}
int main() {
while(~scanf("%d%d%d",&n,&m,&v)) {
for(int i=1;i<=n;++i) scanf("%d",&w[i]);
for(int i=1;i<=n;++i) scanf("%d",&b[i]);
int x,y;
memset(mp,0,sizeof(mp));
for(int i=1;i<=m;++i) {
scanf("%d%d",&x,&y);
mp[x][y]=mp[y][x]=1;
}
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;++i) {
if(vis[i]) continue;
num=sumw=sumb=0;dfs(i);
for(int j=v;j>=0;--j) {
if(j>=sumw) d[j]=max(d[j],d[j-sumw]+sumb);
for(int k=1;k<=num;++k) {
if(j>=w[a[k]]) d[j]=max(d[j],d[j-w[a[k]]]+b[a[k]]);
}
}
}
printf("%d\n",d[v]);
}
return 0;
}
题意:n对情侣(1~2n)围成一圈,给出所有情侣的配对。要分发两件物品。分发规则是:情侣的不一样,相邻两个的不一样。求分配方式。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define de(x) cout << #x << "=" << x << endl
const int N=200005;
struct Edge {
int pre,to;
}e[N*4];
struct Node {
int x,y;
}node[N];
int last[N],ans[N],vis[N];
int sz,m;
void adde(int u,int v) {
e[++sz].to=v;
e[sz].pre=last[u];
last[u]=sz;
}
void inite() {
sz=0;
memset(last,-1,sizeof(last));
}
void dfs(int u,int val) {
++m;
vis[u]=1;
ans[u]=val;
for(int i=last[u];i!=-1;i=e[i].pre) {
int v=e[i].to;
if(vis[v]) continue;
dfs(v,val^1);
break;
}
}
int main() {
int n;
while(~scanf("%d",&n)) {
int u,v;inite();
for(int i=1;i<=n;++i) {
scanf("%d%d",&u,&v);
node[i].x=u;
node[i].y=v;
adde(u,v);adde(v,u);
adde(i*2-1,i*2);
adde(i*2,i*2-1);
}
for(int i=1;i<=n*2;++i) {
if(vis[i]) continue;
m=0;dfs(i,0);
if(m&1) {
puts("-1");
return 0;
}
}
for(int i=1;i<=n;++i) {
u=node[i].x;
v=node[i].y;
printf("%d %d\n",ans[u]+1,ans[v]+1);
}
}
return 0;
}