0
点赞
收藏
分享

微信扫一扫

AtCoder Regular Contest 076


C - Reconciled?

Time Limit: 2 sec / Memory Limit: 256 MB

Score : 300300 points

Problem Statement

Snuke has NN dogs and MM monkeys. He wants them to line up in a row.

As a Japanese saying goes, these dogs and monkeys are on bad terms. ("ken'en no naka", literally "the relationship of dogs and monkeys", means a relationship of mutual hatred.) Snuke is trying to reconsile them, by arranging the animals so that there are neither two adjacent dogs nor two adjacent monkeys.

How many such arrangements there are? Find the count modulo 109+7109+7 (since animals cannot understand numbers larger than that). Here, dogs and monkeys are both distinguishable. Also, two arrangements that result from reversing each other are distinguished.

Constraints

  • 1≤N,M≤1051≤N,M≤105

Input

Input is given from Standard Input in the following format:

NN MM

Output

Print the number of possible arrangements, modulo 109+7109+7.

Sample Input 1 Copy

Copy

2 2

Sample Output 1 Copy

Copy

8

We will denote the dogs by ​​A​​​ and ​​B​​​, and the monkeys by ​​C​​​ and ​​D​​​. There are eight possible arrangements: ​​ACBD​​​, ​​ADBC​​​, ​​BCAD​​​, ​​BDAC​​​, ​​CADB​​​, ​​CBDA​​​, ​​DACB​​​ and ​​DBCA​​.

Sample Input 2 Copy

Copy

3 2

Sample Output 2 Copy

Copy

12

Sample Input 3 Copy

Copy

1 8

Sample Output 3 Copy

Copy

0

Sample Input 4 Copy

Copy

100000 100000

Sample Output 4 Copy

Copy

530123477

 

题意:

n只猴子,m条狗,狗与狗不能互相挨着,猴与猴不能互相挨着。

这样的排列方式有多少种?请输出答案对 10^9+71取模的结果。

题意:

水题。

>=2 ans=0

==1 ans=n!*m!

==0 ans=n!*m!*2(可以换位置)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=3*100005;
const int MOD=1e9+7;
LL cal(LL n)
{
LL ans=1;
for(int i=1;i<=n;i++)
{
ans=(ans%MOD*i%MOD)%MOD;
}
return ans%MOD;
}
int main()
{
LL n,m;
scanf("%lld%lld",&n,&m);
if(llabs(m-n)>=2)
{
cout<<0<<endl;
}
else
{
int k;
if(llabs(m-n)==1)
{
k=1;
}
else
k=2;
cout<<((cal(n)*cal(m))*k)%MOD<<endl;
}

return 0;

}

 

D - Built?

Time Limit: 2 sec / Memory Limit: 256 MB

Score : 500500 points

Problem Statement

There are NN towns on a plane. The ii-th town is located at the coordinates (xi,yi)(xi,yi). There may be more than one town at the same coordinates.

You can build a road between two towns at coordinates (a,b)(a,b) and (c,d)(c,d) for a cost of min(|a−c|,|b−d|)min(|a−c|,|b−d|) yen (the currency of Japan). It is not possible to build other types of roads.

Your objective is to build roads so that it will be possible to travel between every pair of towns by traversing roads. At least how much money is necessary to achieve this?

Constraints

  • 2≤N≤1052≤N≤105
  • 0≤xi,yi≤1090≤xi,yi≤109
  • All input values are integers.

Input

Input is given from Standard Input in the following format:


NN x1x1 y1y1 x2x2 y2y2 : xNxN yNyN


Output

Print the minimum necessary amount of money in order to build roads so that it will be possible to travel between every pair of towns by traversing roads.

Sample Input 1 Copy

Copy


3 1 5 3 9 7 8


Sample Output 1 Copy

Copy


3


Build a road between Towns 11 and 22, and another between Towns 22 and 33. The total cost is 2+1=32+1=3 yen.

Sample Input 2 Copy

Copy


6 8 3 4 9 12 19 18 1 13 5 7 6


Sample Output 2 Copy

Copy


8


题意:

平面上有n个城市的坐标(x,y),两个城市之间的距离为min(|a−c|,|b−d|),建造最短的路以便可以任意两个城市都可以到达。

分析:

最小生成树的裸题,但关键是边不好建立,或超内存,所以需要贪心的选一下边,因为距离=min(|x1-x2|,|y1-y2|);

所以我们直接先按x排序,保证选取|x1-x2|的最小的n-1条边,y同理

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100005;
const int MOD=1e9+7;
LL dist[N];
bool vis[N];
int head[N],tot=0,fa[N];

struct node
{
int from,to;
LL w;
int next;
} edge[N*4];
bool operator<(node a,node b)
{
return a.w<b.w;
}
void add(int u,int v,LL w)
{
edge[tot].from=u;
edge[tot].to=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
}
int n;

int get(int x)
{
if(x==fa[x])
return x;
else
return fa[x]=get(fa[x]);
}
struct Point
{
int x,y;
int id;
}p[N];
bool cmp1(Point a,Point b)
{
return a.x<b.x;
}
bool cmp2(Point a,Point b)
{
return a.y<b.y;
}
int main()
{
memset(head,-1,sizeof(head));
tot=0;


scanf("%d",&n);

for(int i=1; i<=n; i++)
fa[i]=i;


for(int i=1; i<=n; i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
p[i].id=i;
}
sort(p+1,p+n+1,cmp1);
for(int i=2;i<=n;i++)
{
add(p[i-1].id,p[i].id,p[i].x-p[i-1].x);
}
sort(p+1,p+n+1,cmp2);
for(int i=2;i<=n;i++)
{
add(p[i-1].id,p[i].id,p[i].y-p[i-1].y);
}


sort(edge,edge+tot);
int cnt=0;
LL ans=0;
for(int i=0; i<tot; i++)
{

int fu=get(edge[i].from);
int fv=get(edge[i].to);
if(fu!=fv)
{


fa[fu]=fv;
cnt++;
ans+=edge[i].w;
if(cnt==n-1)
break;

}
}
cout<<ans<<endl;

return 0;

}

 

举报

相关推荐

0 条评论