【 2013 Multi-University Training Contest 6 】

时间:2022-09-12 18:05:23

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 】的更多相关文章

  1. 【 2013 Multi-University Training Contest 8 】

    HDU 4678 Mine 对于每个空白区域,求SG值. 最后异或起来等于0,先手必败. #pragma comment(linker,"/STACK:102400000,102400000 ...

  2. 【 2013 Multi-University Training Contest 7 】

    HDU 4666 Hyperspace 曼哈顿距离:|x1-x2|+|y1-y2|. 最远曼哈顿距离,枚举x1与x2的关系以及y1与y2的关系,取最大值就是答案. #include<cstdio ...

  3. 【 2013 Multi-University Training Contest 5 】

    HDU 4647 Another Graph Game 如果没有边的作用,显然轮流拿当前的最大值即可. 加上边的作用,将边权平均分给两个点,如果一个人选走一条边的两个点,就获得了边的权值:如果分别被两 ...

  4. 【 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 ...

  5. 【 2013 Multi-University Training Contest 3 】

    HDU 4622 Reincarnation 枚举字符串的起点,构造后缀自动机,每次插入一个字符,就能统计得到当前不同字串的个数,预处理出所有的询问. #include<cstdio> # ...

  6. 【 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. ...

  7. 【 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 ...

  8. 【HDU 2014 Multi-University Training Contest 1 1002】&sol;【HDU 4862】Jump

    多校训练就这么华丽丽的到了 ,于是乎各种华丽丽的被虐也開始了. 这是多校的1002; 最小费用最大流. 题目大意: 有n*m个方格,每一个方格都一个的十进制一位的数.你能够操作K次. 对于每一次操作, ...

  9. 【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 ...

随机推荐

  1. java虚拟机之引用

    强引用: 类似:object A=new Object();这样的引用,只要强引用还存在,垃圾回收期就永远不会回收被引用的对象,eg:这里的new Oject().   软引用: 一些还有用,但是非必 ...

  2. 20145206《Java程序设计》第9周学习总结

    20145206 <Java程序设计>第9周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作 ...

  3. post 与 get 在转码的区别

    前端输入中文的时候,后端post通过 String text = getRequest().getParameter("text");可以正常拿到中文, 但是通过get的时候就会出 ...

  4. JAVA基础知识之多线程——控制线程

    join线程 在某个线程中调用其他线程的join()方法,就会使当前线程进入阻塞状态,直到被join线程执行完为止.join方法类似于wait, 通常会在主线程中调用别的线程的join方法,这样可以保 ...

  5. CSS 设置TABLE 表格 边框

    /*table列表 合并边框设置*/ .tablelist { border-collapse:collapse; } /*table列表 设置边框宽度及颜色*/ .tablelist td { bo ...

  6. 乐酷工作室孙志伟:Testin云測试有广度有深度 省钱省力值得信赖

    乐酷工作室孙志伟:Testin云測试有广度有深度 省钱省力值得信赖 2014/10/16 · Testin · 开发人员訪谈 乐酷工作室是一个专业从事移动终端应用及游戏自主研发和运营的创业团队,眼下拥 ...

  7. (转)Sublime Text2 快捷键汇总

    场景:最近在编写项目中越发的感觉到一个得心应手的编辑器是多么的重要,而sublime,无疑是让我用着最舒服,最有感觉的编辑器了! 1 快捷键总结 一个好的编辑器,能大大提高编程的效率.如果能熟知软件的 ...

  8. IPFS开发团队是如何工作的?

    小编不是一个很八卦的人,连当红明星都认不全.不过,今天还是带领大家来扒一扒ipfs开发团队是如何工作的. 工作方式: 全体会议:每周一有一个全体会议,这个会议是提前安排好的一个日程 任务讨论:把大任务 ...

  9. 前端基于Canvas生成等值面的方案

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在之前的项目中,我们做过基于PM2.5的站点监测数据对全区域进 ...

  10. SkylineGlobe 6&period;6 开放的事件函数接口

    SkylineGlobe 6.6 开放的事件函数接口: struct __declspec(uuid("84ce9e1b-65ad-11d5-85c1-0001023952c1") ...