codeforces contest 742

http://codeforces.com/contest/742


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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;
}





//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

D  741B  Arpa's weak amphitheater and Mehrdad's valuable Hoses
题意:n个物品,m个关系,总空间v。每个物品有花费w和价值b。m个关系类似于并查集的朋友关系。选取物品的规则是:对于一个关系圈,要么不选,要么只选一个,要么全选,求最大价值。
题解:01背包。
#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;
}



//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
E  741C  Arpa’s overnight party and Mehrdad’s silent entering
题意:n对情侣(1~2n)围成一圈,给出所有情侣的配对。要分发两件物品。分发规则是:情侣的不一样,相邻两个的不一样。求分配方式。
题解:连边情侣和<i*2-1, i*2>,构成的环如果是奇环就无解。偶环肯定能拆成二部图。
事实上不会有奇环。
#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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值