CF339
有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");
}
}
很裸的一个线段树了。
#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的更多相关文章
随机推荐
- Codevs 5126 推销员 2015年NOIP全国联赛普及组
5126 推销员 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死 ...
- UvaLive7362 Fare(欧拉函数)
题意:求1~n的素因子之和. 分析:欧拉函数 #include<cstdio> #include<cstring> #include<cctype> #includ ...
- Winform的窗体美化心酸路
我想做一位狂热的程序猿粪子! 其实一直都很想做点什么,工作原因林林种种导致停止了前进的脚步. 有时会为自己的一个目标狂热,但经常发觉激情过后更多的总是为自己找借口! 最近感觉奔三将近.逐有感而发,不能 ...
- tomcat源码解读(1)–tomcat热部署实现原理
tomcat的热部署实现原理:tomcat启动的时候会有启动一个线程每隔一段时间会去判断应用中加载的类是否发生变法(类总数的变化,类的修改),如果发生了变化就会把应用的启动的线程停止掉,清除引用,并且 ...
- Spark小课堂Week4 从控制台看Spark逻辑结构
Spark小课堂Week4 从控制台看Spark逻辑结构 层级关系: 从监控控制台,我们可以看到如下关系: 一个 Job 包含 n Stage 一个 Stage 包含 n Task Job0解决什么问 ...
- python字典操作
Python字典是另一种可变容器模型,且可存储任意类型对象,如字符串.数字.元组等其他容器模型.一.创建字典字典由键和对应值成对组成.字典也被称作关联数组或哈希表.基本语法如下: 代码如下: dict ...
- opencv学习笔记(02)——遍历图像(指针法)
#include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <ope ...
- Python socket模拟HTTP请求
0x00 起 最近在做一个对时间要求比较高的扫描器,需要封装一下SOCKET模拟HTTP发包的一些常用函数.简单的说,就是重写一下requests中的get.post方法. 今天在写的时候,遇到一枚很 ...
- 简单3d RPG游戏 之 003 怪物AI
游戏中,怪物会自动的往玩家所在地点走去,那需要创建一个C#脚本EnemyAI,包含两个功能: 1. 怪物旋转自己对准玩家 2. 怪物向前移动,追逐玩家 public class EnemyAI : M ...
- Real-Time Rendering 3 彩图
电子版只有黑白图,彩图见官网链接:http://www.realtimerendering.com/book.html.虽然只有部分彩图,不过够用了,下面是其中几幅图,如果只能看黑白的,那得多蛋疼: