C. Xenia and Weights

有1...10k的砝码,在天枰上,左右轮流放置砝码,要求之后左右轮流比另一侧重量要大,要求相邻两次砝码不能相同。

解题报告给出(i,j,k)表示balance,j表示最后一次的砝码重量,k表示第几步,然后表示从点(0,0,0)->(x,y,m)的图论问题,跟动态规划是等价的,复杂度是O(w^3*m)。

我给出了一个比上述算法更优的一个算法,做法是用dp[i][j]表示第i步balance达到j时的所有可能的砝码情况的二进制mask,复杂度是O(w^2*m),但要求w<32。

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std; int dp[][];
char w[]; int main() {
int m;
scanf("%s%d", w, &m); memset(dp, , sizeof(dp));
dp[][] = ; for (int i = ; i <= m; i++) {
for (int j = ; j <= ; j++) {
if (dp[i - ][j] > ) {
for (int k = ; k <= ; k++) if (w[k - ] == '') {
if (dp[i - ][j] ^ ( << k)) {
if (j >= && j - k < ) {
dp[i][j - k] |= ( << k);
} else if (j < && j + k > ) {
dp[i][j + k] |= ( << k);
}
}
}
}
}
} int ans_j = -;
for (int j = ; j <= ; j++) if (dp[m][j] > )
ans_j = j; if (ans_j == -) {
printf("NO\n");
} else {
printf("YES\n");
int i = m;
vector<int> ans;
int last = ;
while (i > ) {
for (int j = ; j <= ; j++) {
if (dp[i][ans_j] & ( << j)) {
if (j == last) continue; ans.push_back(j); if (ans_j >= ) ans_j -= j;
else ans_j += j; last = j; break;
}
}
i--;
}
for (i = ans.size() - ; i >= ; i--) {
printf("%d ", ans[i]);
}
printf("\n");
}
}

D. Xenia and Bit Operations

很裸的一个线段树了。

#include <cstdio>
#include <iostream>
using namespace std; const int MAXN = << ; int num[MAXN]; class SegNode {
public:
int L, R;
int level, sum;
} node[MAXN * ]; class SegTree {
public:
void build(int r, int L, int R) {
node[r].L = L;
node[r].R = R; if (L == R) {
// leaf
node[r].level = ;
node[r].sum = num[L];
} else {
// non leaf
int M = (L + R) / ;
build( * r, L, M);
build( * r + , M + , R);
node[r].level = node[ * r].level + ;
if (node[r].level & ) {
node[r].sum = node[ * r].sum | node[ * r + ].sum;
} else {
node[r].sum = node[ * r].sum ^ node[ * r + ].sum;
}
}
}
void update(int r, int p, int b) {
if (node[r].L == node[r].R) {
node[r].sum = b;
} else {
if (p <= node[ * r].R) {
// left
update( * r, p, b);
} else if (p >= node[ * r + ].L) {
// right
update( * r + , p, b);
}
if (node[r].level & ) {
node[r].sum = node[ * r].sum | node[ * r + ].sum;
} else {
node[r].sum = node[ * r].sum ^ node[ * r + ].sum;
}
}
}
} tree; int main() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i <= ( << n); i++) {
scanf("%d", &num[i]);
}
tree.build(, , << n);
for (int i = ; i < m; i++) {
int p, b;
scanf("%d%d", &p, &b);
tree.update(, p, b);
printf("%d\n", node[].sum);
}
}

CF339的更多相关文章

随机推荐

  1. union 中可以存储的是不带构造函数的类对象

    union 中可以存储的是不带构造函数的类对象 否则不符合逻辑 为什么不符合逻辑?

  2. 选择问题(选出第i个最小元素)

    通过分治法解决的分析(还有其他方法解决选择问题如使用 堆) 1 同快速排序一样,对输入的数组进行递归分解 不同的是:快速排序会递归处理分解的两边,而选择问题只处理需要的一边 2 选择问题的期望时间代价 ...

  3. 支持 IE8 IE11 和 FF, Chrome 浏览器的圆角

    .rounded-corners { position: relative behavior: url(/Styles/PIE.htc); //这里一定是“/”根目录 border-radius: 2 ...

  4. maven增量编译

    最近由于不清楚maven(2.2.x)增量编译的机制,导致应用出现了一个当时觉得非常诡异的一个问题.先描述一下问题.     背景是应用A有一个公用的base包,版本为1.6.6-SNAPSHOT,应 ...

  5. sublime 设置localhost 2

    最近sidebar用不了了,提示更新然后就自动卸载了: 研究了下其他方式实现: Sublime Text 2 Sublime Text 3 都可以使用: 菜单 --> Tools --> ...

  6. 一个不错的图片滑动展示插件 anythingslider

    一个不错的图片http://css-tricks.com/anythingslider-jquery-plugin/ DEMO演示: http://css-tricks.github.io/Anyth ...

  7. html lang

    目前,语言的标签表示法的国际标准是RFC 4646,名称是<Tags for Identifying Languages>.简单说,这个文件规定,一种语言的标签应该按照如下方式排列: la ...

  8. table如何在过宽的时候添加滚动条

    在页面中,往往由于一个table的列过于多,导致页面放不下,然后内容各种挤变形. 这里说一个解决方法,.先用一个DIV把TABLE包围起来.然后给这个DIV设置宽度,并且设置overflow:auto ...

  9. Selenium+python+shell+crontab+firefox

    最近在尝试一个自动打卡的脚本,发现了几个问题,特此记录一下. 环境: Ubuntu 12.04.4 LTS selenium 2.43.0 firefox 32.0.3 1 本来机器上selenium ...

  10. 1036. Boys vs Girls (25)

    #include <stdio.h>#include <string.h>int main(){ int n,i; while(scanf("%d",&am ...