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】/【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. Spring+quartz整合问题

    今天一开始在弄quartz的时候用的2.0.2的jar包整合Spring3.0.5的时候报错 Java.lang.IncompatibleClassChangeError: class org.spr ...

  2. 文本数据源Fields Format

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  3. Hbase的配置和安装

    Hbase的配置和安装 1. 解压hbase.配置HBASE_HOME tar -zxvf hbase-1.2.4.tar.gz 2. 修改$HBASE_HOME/conf/hbase-env.sh文 ...

  4. VIM小技巧

    1.复制多行 vi编辑器中的整行(多行)复制与粘贴就非常必要了. 1.复制 1)单行复制 在命令模式下,将光标移动到将要复制的行处,按"yy"进行复制: 2)多行复制 在命令模式下 ...

  5. RedHat下Bugzilla的安装和配置

    Bugzilla 是一个开源的缺陷跟踪系统(Bug-Tracking System). OS:RedHat Linux 软件类型:开源 架构:B/S server端模块开发语言:perl(c/c++) ...

  6. 【burp】配置HTTPS抓包方法

    以Chrome为例,配置HTTPS抓包方法 1.获取破解版的burp,将BurpLoader.jar和burpsuite_pro_v1.5.18.jar放到一个路径下 2.在cmd里进入上述两个jar ...

  7. 如何在VISIO 2010/2013 中关闭Shape protection(图形保护)

    最近在画UML图,用到MS visio 2010, 在使用一些网络查找到的图形的时候发现无法编辑,在网上找了找,翻译了下. Visio 2013 的图形保护功能,可以锁定图形的某些特定属性,使其无法被 ...

  8. 使用 Box2D 做一个 JansenWalker 机器人

    在 Box2DFlash 的官网的首页有一个小 Demo,这个 Demo 中有11个例子,可以通过左右方向键查看不同的例子,里面的每个例子都非常有趣,但最让我感兴趣的,是其中一个叫 JansenWal ...

  9. html/css小练习3

    效果图:

  10. html/css小练习2

    效果图: