【 2013 Multi-University Training Contest 6 】
HDU 4655 Cut Pieces
假设n个数构成的总数都分成了n段,总数是n*a1*a2*...*an。但是答案显然不会那么多。
对于相邻的两个ai,ai+1,如果选择相同的颜色,那么就减少了a1*a2*...*ai-1*min(ai,ai+1)*ai+2*ai+3*...*an。
不妨假设n=3,三个数分别是a,b,c。且a<b<c。
对于所有的排列,只有a,c,b是最优的,结果是3*a*b*c-a*b-b。
当n>3的时候同样可以得到结论:a1,an,a2,an-1...使得总的段数最多。
#include<cstdio>
#include<algorithm>
#include<iostream>
typedef long long LL;
#define MOD 1000000007
#define MAXN 1000010
using namespace std;
int arr[MAXN];
int tmp[MAXN];
LL ext_gcd(LL a, LL b, LL &x, LL &y) {
LL t, d;
if (b == ) {
x = ;
y = ;
return a;
}
d = ext_gcd(b, a % b, x, y);
t = x;
x = y;
y = t - a / b * y;
return d;
}
LL invmod(LL a, LL n = MOD) {
LL x, y;
if (ext_gcd(a, n, x, y) != )
return -;
return (x % n + n) % n;
}
int main() {
int T;
int n;
int i;
LL ans;
LL res;
LL mul;
int l, r;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
ans = n;
mul = ;
for (i = ; i < n; i++) {
scanf("%d", &arr[i]);
mul *= arr[i];
mul %= MOD;
}
ans *= mul;
ans %= MOD;
sort(arr, arr + n);
for (l = , r = n - , i = ; l <= r; l++, r--) {
if (l == r) {
tmp[i++] = arr[l];
} else {
tmp[i++] = arr[l];
tmp[i++] = arr[r];
}
}
for (i = ; i <= n; i++) {
res = mul * invmod(tmp[i] * (LL) tmp[i - ]);
res %= MOD;
res *= min(tmp[i], tmp[i - ]);
ans -= res % MOD;
ans = (ans % MOD + MOD) % MOD;
}
cout << ans << endl;
}
return ;
}
HDU 4661 Message Passing
由于消息传递的次数要求最少,则一个节点将收集所有它的子树的消息之后,再往父节点传递。
因此,有一个节点将收到所有消息。而发送消息是收集消息的逆过程,总的答案=收集消息的方案数*发送消息的方案数=收集消息的方案数2。
dp[i]表示以i为根的子树,收集到它子孙所有消息的方案数。
size[i]表示以i为根的子树的节点总数。
f[i]表示以i为根的树,收集到它子孙所有消息的方案数。
fac[i]表示i的阶乘。
dp[i]=fac[size[i]-1]。
dp[i]/=fac[size[j]],(j是i的儿子)。
dp[i]*=dp[j],(j是i的儿子)。
#pragma comment(linker,"/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
typedef long long LL;
#define MAXN 1000010
#define MAXM 2000010
#define MOD 1000000007
int n;
LL fac[MAXN];
LL invfac[MAXN];
int first[MAXN], next[MAXM], v[MAXM], e;
bool vis[MAXN];
LL dp[MAXN];
LL f[MAXN];
int size[MAXN];
LL ext_gcd(LL a, LL b, LL &x, LL &y) {
LL t, d;
if (b == ) {
x = ;
y = ;
return a;
}
d = ext_gcd(b, a % b, x, y);
t = x;
x = y;
y = t - a / b * y;
return d;
}
LL invmod(LL a, LL n = MOD) {
LL x, y;
if (ext_gcd(a, n, x, y) != )
return -;
return (x % n + n) % n;
}
void init() {
int i;
fac[] = ;
for (i = ; i < MAXN; i++) {
fac[i] = fac[i - ] * i;
fac[i] %= MOD;
}
for (i = ; i < MAXN; i++) {
invfac[i] = invmod(fac[i]);
}
}
inline void addEdge(int x, int y) {
v[e] = y;
next[e] = first[x];
first[x] = e++;
}
void getSize(int x) {
vis[x] = true;
size[x] = ;
for (int i = first[x]; i != -; i = next[i]) {
int y = v[i];
if (!vis[y]) {
getSize(y);
size[x] += size[y];
}
}
}
void dfs(int x) {
vis[x] = true;
dp[x] = fac[size[x] - ];
for (int i = first[x]; i != -; i = next[i]) {
int y = v[i];
if (!vis[y]) {
dfs(y);
dp[x] *= invfac[size[y]];
dp[x] %= MOD;
dp[x] *= dp[y];
dp[x] %= MOD;
}
}
}
void search(int x, int pre) {
vis[x] = true;
if (pre != -) {
f[x] = fac[n - ]; f[x] *= invfac[n - size[x]];
f[x] %= MOD;
LL tmp = f[pre];
tmp *= invfac[n - ];
tmp %= MOD;
tmp *= fac[n - - size[x]];
tmp %= MOD;
tmp *= fac[size[x]];
tmp %= MOD;
tmp *= invmod(dp[x]);
tmp %= MOD;
f[x] *= tmp;
f[x] %= MOD;
for (int i = first[x]; i != -; i = next[i]) {
int y = v[i];
if (!vis[y]) {
f[x] *= invfac[size[y]];
f[x] %= MOD;
f[x] *= dp[y];
f[x] %= MOD;
}
}
}
for (int i = first[x]; i != -; i = next[i]) {
int y = v[i];
if (!vis[y]) {
search(y, x);
}
}
}
int main() {
int T;
int i;
int x, y;
int ans;
init();
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
e = ;
memset(first, -, sizeof(first));
for (i = ; i < n; i++) {
scanf("%d%d", &x, &y);
addEdge(x, y);
addEdge(y, x);
}
memset(vis, false, sizeof(vis));
getSize();
memset(vis, false, sizeof(vis));
dfs();
memset(vis, false, sizeof(vis));
f[] = dp[];
search(, -);
ans = ;
for (i = ; i <= n; i++) {
ans += (f[i] * f[i]) % MOD;
ans %= MOD;
}
printf("%d\n", ans);
}
return ;
}
HDU 4662 MU Puzzle
从给定的字符串变成MI需要反着操作。
(1)将U替换成III。
(2)添加x个UU,即添加x个IIIIII。
假设有cnt个I,添加x个UU,那么一共有cnt+6x个I,又要满足cnt+6x=2y。判断是否存在这样的x满足方程即可。
#include<cstdio>
#include<cstring>
#define MAXN 1000010
char str[MAXN];
bool isOK(int len) {
if (str[] != 'M') {
return false;
}
for (int i = ; i < len; i++) {
if (str[i] == 'M') {
return false;
}
}
return true;
}
int main() {
int T;
int len;
int cnt;
int i;
scanf("%d", &T);
while (T--) {
scanf(" %s", str);
len = strlen(str);
if (isOK(len)) {
cnt = ;
for (i = ; i < len; i++) {
if (str[i] == 'U') {
cnt += ;
} else {
cnt++;
}
}
if (len == && str[] == 'I') {
puts("Yes");
} else if (cnt % == || cnt % == ) {
puts("Yes");
} else {
puts("No");
}
} else {
puts("No");
}
}
return ;
}
HDU 4664 Triangulation
SG打表找规律。
mex是不属于这个集合的最少非负整数。
sg(x)是mex{sg(y)|y是x的后继状态}。
游戏和的SG函数值是它的所有子游戏SG函数值的异或。
n个游戏的异或和为0,先手必败。
#include<cstdio>
#include<cstring>
#define MAXN 1010
int sg[MAXN];
bool vis[MAXN];
int SG(int n) {
if (n == ) {
sg[n] = ;
} else if (n == ) {
sg[n] = ;
} else if (n == ) {
sg[n] = ;
} else if (n == ) {
sg[n] = ;
} else if (sg[n] == -) {
int i;
memset(vis, false, sizeof(vis));
for (i = ; i <= n - ; i++) {
vis[SG(i) ^ SG(n - i - )] = true;
}
for (i = ;; i++) {
if (!vis[i]) {
break;
}
}
sg[n] = i;
}
return sg[n];
}
void init() {
int i;
memset(sg, -, sizeof(sg));
for (i = ; i < MAXN; i++) {
sg[i] = SG(i);
}
}
int getSG(int n) {
if (n < MAXN) {
return sg[n];
} else {
return sg[n % + * ];
}
}
int main() {
int T;
int n;
int tmp;
int res;
init();
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
res = ;
while (n--) {
scanf("%d", &tmp);
res ^= getSG(tmp);
}
if (res) {
puts("Carol");
} else {
puts("Dave");
}
}
return ;
}
HDU 4665 Unshuffle
若一个数只出现两次,则第一个数属于0,第二个数属于1。
若一个数出现了四次,则第一个数属于0,第四个数属于1,其他两个都有可能。
#include<cstdio>
#include<cstring>
#include<vector>
#define MAXN 2010
using namespace std;
int arr[MAXN];
char str[MAXN];
bool flag;
int idx[MAXN];
int cnt[MAXN];
int st[][MAXN];
int belong[MAXN];
int n;
vector<int> pos[MAXN];
void dfs(int x, int p1, int p2) {
if (x > n) {
flag = true;
}
if (flag) {
return;
}
if (p1 > && p2 >
&& arr[st[][min(p1, p2)]] != arr[st[][min(p1, p2)]]) {
return;
}
if (belong[x] == ) {
st[][p1 + ] = x;
dfs(x + , p1 + , p2);
} else if (belong[x] == ) {
st[][p2 + ] = x;
dfs(x + , p1, p2 + );
} else {
st[][p1 + ] = x;
belong[pos[arr[x]][]] = ;
dfs(x + , p1 + , p2); if (!flag) {
st[][p2 + ] = x;
belong[pos[arr[x]][]] = ;
dfs(x + , p1, p2 + ); belong[pos[arr[x]][]] = -;
}
}
}
int main() {
int T;
int i;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
memset(idx, , sizeof(idx));
memset(cnt, , sizeof(cnt));
for (i = ; i <= n; i++) {
scanf("%d", &arr[i]);
cnt[arr[i]]++;
idx[i] = cnt[arr[i]];
pos[arr[i]].clear();
}
memset(belong, -, sizeof(belong));
for (i = ; i <= n; i++) {
if (idx[i] == ) {
belong[i] = ;
} else if (idx[i] == && cnt[arr[i]] == ) {
belong[i] = ;
} else if (idx[i] == ) {
belong[i] = ;
}
pos[arr[i]].push_back(i);
}
flag = false;
dfs(, , );
for (i = ; i <= (n >> ); i++) {
str[st[][i]] = '';
str[st[][i]] = '';
}
for (i = ; i <= n; i++) {
putchar(str[i]);
}
putchar('\n');
}
return ;
}
【 2013 Multi-University Training Contest 6 】的更多相关文章
- 【 2013 Multi-University Training Contest 8 】
HDU 4678 Mine 对于每个空白区域,求SG值. 最后异或起来等于0,先手必败. #pragma comment(linker,"/STACK:102400000,102400000 ...
- 【 2013 Multi-University Training Contest 7 】
HDU 4666 Hyperspace 曼哈顿距离:|x1-x2|+|y1-y2|. 最远曼哈顿距离,枚举x1与x2的关系以及y1与y2的关系,取最大值就是答案. #include<cstdio ...
- 【 2013 Multi-University Training Contest 5 】
HDU 4647 Another Graph Game 如果没有边的作用,显然轮流拿当前的最大值即可. 加上边的作用,将边权平均分给两个点,如果一个人选走一条边的两个点,就获得了边的权值:如果分别被两 ...
- 【 2013 Multi-University Training Contest 4 】
HDU 4632 Palindrome subsequence dp[x][y]表示区间[x,y]构成回文串的方案数. 若str[x]==str[y],dp[x][y]=dp[x+1][y]+dp[x ...
- 【 2013 Multi-University Training Contest 3 】
HDU 4622 Reincarnation 枚举字符串的起点,构造后缀自动机,每次插入一个字符,就能统计得到当前不同字串的个数,预处理出所有的询问. #include<cstdio> # ...
- 【 2013 Multi-University Training Contest 2 】
HDU 4611 Balls Rearrangement 令lcm=LCM(a,b),gcd=GCD(a,b).cal(n,a,b)表示sum(abs(i%a-i%b)),0<=i<n. ...
- 【 2013 Multi-University Training Contest 1 】
HDU 4602 Partition f[i]表示和为i的方案数.已知f[i]=2i-1. dp[i]表示和为i,k有多少个.那么dp[i]=dp[1]+dp[2]+...+dp[i-1]+f[i-k ...
- 【HDU 2014 Multi-University Training Contest 1 1002】/【HDU 4862】Jump
多校训练就这么华丽丽的到了 ,于是乎各种华丽丽的被虐也開始了. 这是多校的1002; 最小费用最大流. 题目大意: 有n*m个方格,每一个方格都一个的十进制一位的数.你能够操作K次. 对于每一次操作, ...
- 【2018 Multi-University Training Contest 5】
01: 02:https://www.cnblogs.com/myx12345/p/9436953.html 03: 04: 05:https://www.cnblogs.com/myx12345/p ...
随机推荐
- 基于springMVC+angular+bootstrap+mysql的简易购物网站搭建
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=10&cad=rja& ...
- Excel与Word套打功能使用技巧及EXCEL数据处理成绩
Excel与Word套打功能使用技巧 婚礼邀请友人参加,就需要写请柬.而且写请柬不但要求字写得端正,还不能有错别字,再加上邀请的朋友多,写请柬就是一个劳累活.这时我们利用Word的套打功能,就会让写请 ...
- php : 基础(4)
流程控制 循环结构 循环的中断 循环中,有两种中断语句可以使用: break: 用于完全终止某个循环,让执行流程进入到循环语句后面的语句: continue: 用于停止当前正在进行的当次循环,而进入到 ...
- sql 删除数据库表 外键
--/第1步**********删除所有表的外键约束*************************/ DECLARE c1 cursor for select 'alter table ['+ ...
- VS中Qt的探索02
边看C++ GUI QT4教程,边在VS2010中进行编程学习探索. 在使用Qt设计师时,其中每一个对象的ObjectName属性是非常重要的,在程序功能的实现过程中,需要不断的使用该变量名. 当所有 ...
- Address already in use: JVM_Bind:8080 的解决办法<转>
出错情况:运行 Tomcat 时报错 含义:8080 位置显示的端口被其他进程占用 解决方法: 方法1: 开始--运行--cmd 进入命令提示符 输入netstat -ano 即可看到所有连接的PID ...
- 打开hibernate文件报警告
在web工程中新建一个,Hibetnate项目,打开配置文件报警高错误,This project is not a MyEclipse Hiberbate Project. Assuming Hibe ...
- java 的 linq,不要再写令人讨厌的 for 了!
package com.ly.linq; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator ...
- python之萌新入门的第一天
新人的挑战一:配置环境变量及正确地使用工具. 配置环境好难,照着教程做很简单,但是确定环境配置成功好难. 一开始运行helloworld程序的文件时一直出现SyntaxError:invaild sy ...
- 学习iOS
最近想学习一下iOS开发,不过一点基础都没有,得先从熟悉object-C语法开始,在此把学习中的一些知识点作为记录. mac pro常用操作 学习ios[1]Objective-C 基本语法 学习io ...