HGOI 20191106
HGOI 20191106
t1 旅行家(traveller)
2s,256MB
【题目背景】
小X热爱旅行,他梦想有一天可以环游全世界……
【题目描述】
现在小X拥有n种一次性空间转移装置,每种装置可以使他前进ai光年,每种装置他拥有bi个。(小X作为一个旅行家,是不会后退的;他的初始坐标是0)
他突然对宇宙的根源感到十分好奇,他发现他用完所有的装置刚好能够到达,于是她就开始了他的旅行。
邪恶的光明法师小S听说了这件事,他决定阻止可爱的小X,于是他使出了扭转乾坤的神通,在前进道路上的m个节点上创造出了可以吞噬一切的黑洞,它们的坐标分别是ci。
小X当然不希望旅行失败,为了嘲讽小S,他想知道他有多少种不同的方式到达宇宙的根源。但是小X也不想过分麻烦你,所以他只想知道答案对100000007取模以后的结果。
注意:每种装置本质相同,即连续使用多次同种装置,但顺序不同算作1种。
【输入格式】
第一行一个正整数n,表示小X拥有的一次性空间转移装置的数量。
接下来n行每行两个正整数ai,bi,分别表示该装置可以使他前进ai光年,他拥有bi个该装置。
接下来一行一个正整数m,表示小S制造出的黑洞数目。
接下来一行m个正整数ci,表示黑洞所在的坐标。
【输出格式】
一行一个正整数,表示答案对100000007取模以后的结果。
【样例输入输出】
traveller.in
2
2 1
3 1
1
1
traveller.out
2
【样例解释】
1号节点存在黑洞,不能通行。
合法的方式为:先使用装置1,再使用装置2;先使用装置2,再使用装置1。
【数据范围】
对于30%的数据,n≤3,bi≤5,m≤3。
对于另外20%的数据,n≤5,bi≤10,ai≤100。
对于另外10%的数据,m=0。
对于另外10%的数据,ai≤100。
对于100%的数据,n≤6,m≤105,0<ci<∑(bi*ai),bi≤12,ai≤109。
题解
显然,所有能被访问到的点是很少的,并且还要求方案,显然一些状态是废的。 我们可以用状态压缩,用 \(f_{a_1 ... a_n}\) 表示当时每一种推进器用了多少个时的方案。
可以使用set<int>
表示不能的到达的点。
转移:
\]
注意到 \(b_i <= 12\) 最多有 13 种方案, 可以状态压缩。
代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define MOD 100000007
using namespace std;
long long reflex[5010000];
long long f[5010000];
set <int> t;
int n, m;
long long a[22];
long long b[22];
long long c[110000];
long long p[20];
void DFS(int x, long long tot, long long prefix){
f[prefix] = tot;
if (t.find(tot) != t.end()) reflex[prefix] = -1; // banned
//cout << prefix << ' ' << f[prefix] << ' ' << reflex[prefix] << endl;
if (x == n+1) return;
for (int i=0;i<=b[x];i++){
DFS(x+1, tot+i*a[x], prefix + p[x] * i);
}
}
int main(){
freopen("traveller.in","r",stdin);
freopen("traveller.out","w",stdout);
p[1] = 1;
for (int i=2;i<=13;i++)
p[i] = p[i-1] * 13;
cin >> n;
int fin = 0;
for (int i=1;i<=n;i++)
cin >> a[i] >> b[i], fin += b[i] * p[i];
// cout << fin << endl;
cin >> m;
for (int i=1;i<=m;i++)
scanf("%lld", c+i), t.insert(c[i]);
DFS(1, 0, 0);
reflex[0] = 1;
for (int i=1;i<=fin;i++){
if (reflex[i] != -1)
for (int j=1;j<=n;j++){
if (i % p[j+1] / p[j] != 0 && reflex[i - p[j]] != -1)
reflex[i] = (reflex[i] + reflex[i - p[j]]) % MOD;
}
}
cout << reflex[fin] << endl;
}
序列(sequence)
2s,512MB
【题目描述】
我们定义一个数对 (x,y)是好的,当且仅当 x≤y,且 x xor y 的二进制表示下有奇数个1。
现在给定 n个区间 [li,ri],你需要对于每个i∈[1,n],输出有几对好的数 (x,y) 满足 x 和 y 都在[l1,r1]∪[l2,r2]...∪[li,ri],即两个数都在前 i 个区间的并里。
【输入格式】
第一行一个正整数 n
接下来 n 行每行两个整数[li,ri],表示第 i 个区间,保证 li≤ri。
【输出格式】
输出 n 行,第 i 行一个整数表示有几对好的数 (x,y) 满足 x,y 都在前 i个区间的并里
【样例输入】
3
1 7
3 10
9 20
【样例输出】
12
25
100
【数据范围】
对于30%的数据,1≤n≤100,1≤li≤ri≤100。
对于50%的数据,1≤n≤1000。
对于100%的数据,1≤n≤100000,1≤li≤ri≤2^31-1。
题解
不妨令 \(T(x)\) 表示 \(x\) 的二进制 1 的个数。
显然两个数 \(a,b\) 异或起来时,\(T(a \mathrm{xor} b) \mod 2 = (T(a) + T(b)) \mod 2\)。
所以答案为
= \sum_{i,j \in A} [T(i) \mod 2 + T(j) \mod 2 = 1] \\
= \sum_{i} [T(i) \mod 2 = 1] \sum_{j} [T(i) \mod 2 = 0]
\]
分别计算 \(\sum_{i} [T(i) \mod 2 = 1]\) 与 \(\sum_{j} [T(i) \mod 2 = 0]\) 即可。
对于区间并,可以离线后用map<int,int>
维护,每一次遇到可行线段删除即可。
代码
#include<bits/stdc++.h>
using namespace std;
long long int reflex[201000]; // reflexing the numbers l, r token
bool vis[201000];
long long int l[101000];
long long int r[101000];
int n;
map <long long int, int> p;
long long odd, even;
// we assume that [l, r)
void calc(int p){ // calc numbers between [ reflex[p], reflex[p+1] )
long long int beg = reflex[p];
long long int end = reflex[p+1];
if (beg & 1){
if (bitset<50>(beg).count() & 1) odd ++;
else even ++;
beg ++;
}
if (beg > end) return;
odd += (end - beg) / 2;
even += (end - beg) / 2;
if ((end - beg) & 1){
if (bitset<50>(end-1).count() & 1) odd ++;
else even ++;
}
}
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
cin >> n;
for (int i=1;i<=n;i++){
scanf("%lld%lld",l+i,r+i);
r[i] ++;
p[l[i]]; p[r[i]];
}
int pl = 0;
typedef map<long long int, int>::iterator Iter;
for (Iter it = p.begin(); it != p.end(); it ++)
it -> second = ++pl, reflex[pl] = it -> first;
for (int i=1;i<=n;i++){
Iter beg = p.lower_bound(l[i]);
Iter end = p.lower_bound(r[i]);
for (Iter it = beg; it != end; it ++)
calc(it -> second);
while (beg != end){
Iter cpy = beg;
beg ++;
p.erase(cpy);
}
printf("%lld\n", odd * even);
}
}
钢琴家(pianist)
1s,256MB
【题目背景】
一年一度的维也纳年度音乐会即将拉开帷幕,由于小X是举世闻名的钢琴家,本次音乐会的导演小Y邀请小X出场演出……
【题目描述】
小X是一位钢琴大师,他对音乐有着自己独特的见解。
维也纳年度音乐会的导演小Y邀请小X参加今年的维也纳年度音乐会,并把自己创作的一张含有S个音符的谱子交给小X,希望他可以在音乐会上弹奏。
由于小X对音乐有着自己独特的见解,他只喜欢n个音乐片段,为了使他在维也纳年度音乐会上可以发挥出最佳水平,他希望他弹奏的谱子是由他喜欢的音乐片段构成的。
但小X又是一个人见人爱、花见花开的通情达理的好孩子,他不希望他对原谱子的改动过多而使小Y伤心难过。由于小X是钢琴大师,日理万机,他没有足够的时间来钻研他最少修改原谱子的多少个音符就可以使原谱子是由他喜欢的音乐片段构成的。所以他希望你直接把修改好后的谱子交给他。
我们假设谱子的音符范围在0-9之间,你需要修改最少的音符,使得原谱子可以分成m个片段,每一个片段小X都喜欢。
【输入格式】
第一行一个长度为S的数字串,表示原谱子。
第二行一个正整数n,表示小X喜欢的片段个数。
接下来n行每行一个数字串,表示小X喜欢的片段。
最后一行10个正整数a[1]-a[10],表示评分标准,当你修改的音符个数<=a[i]时,你可以得到i分。
【输出格式】
m行每行一个片段(请按照原数字串顺序输出这m个片段),为修改后的答案。
pianist.in
12341122334
3
12
34
123
11 10 9 8 7 6 5 4 3 2
pianist.out
12
34
12
123
34
题解
考虑动态规划。
令 \(f_{i}\) 表示在第 \(i\) 的位置时的最优解,普通转移即可(莫名其妙的)。
代码
#include<bits/stdc++.h>
using namespace std;
string s;
string st[110];
string ans[1100];
int f[1100];
int opt[1100];
int calc(int nx, string &t){
int len = t.length();
int ret = (nx + 1 == len ? 0 : f[nx - len]);
for (int i=nx-len+1, j=0;j<len;i++, j++){
if (s[i] != t[j]) ret ++;
}
return ret;
}
int main(){
freopen("pianist.in","r",stdin);
freopen("pianist.out","w",stdout);
cin >> s;
int S = s.length();
int n;
cin >> n;
for (int i=1;i<=n;i++){
cin >> st[i];
}
memset(f, 0x3f, sizeof(f));
for (int i=0;i<S;i++){
for (int j=1;j<=n;j++){
int len = st[j].length();
if (len <= i + 1){
if (calc(i, st[j]) < f[i]){
f[i] = calc(i, st[j]);
opt[i] = j;
}
}
}
}
int pl = S-1;
int nx = 0;
while (pl != -1)
{
ans[++nx] = st[opt[pl]];
pl -= st[opt[pl]].length();
}
while (nx){
cout << ans[nx] << endl;
nx --;
}
}
HGOI 20191106的更多相关文章
- HGOI 20191106 题解
Problem A 旅行者 有$n$种转移装置,每种转移装置本质相同,每种装置可以前进$a_i$单位,但只有$b_i$个. 从初始坐标为$0$出发,途中不能经过$c_1,c2,...,c_m$中的任 ...
- HGOI 20181028 题解
HGOI 20181028(复赛备考) /* 真是暴力的一天,最后一题MLE?由于数组开得太大了!!! 270滚粗 考场上好像智商高了很多?!(假的) */ sol:暴力求解,然后没有数据范围吐槽一下 ...
- HGOI NOIP模拟4 题解
NOIP国庆模拟赛Day5 题解 T1 马里奥 题目描述 马里奥将要参加 NOIP 了,他现在在一片大陆上,这个大陆上有着许多浮空岛,并且其中一座浮空岛上有一个传送门,马里奥想要到达传送门从而前往 N ...
- [20191106]善用column格式化输出.txt
[20191106]善用column格式化输出.txt # man columnDESCRIPTION The column utility formats its input into mu ...
- GoCN每日新闻(2019-11-06)
GoCN每日新闻(2019-11-06) GoCN每日新闻(2019-11-06) 1. 使用构建标签分离你的测试文件 https://mickey.dev/posts/go-build-tags-t ...
- 「HGOI#2019.4.19省选模拟赛」赛后总结
t1-Painting 这道题目比较简单,但是我比较弱就只是写了一个链表合并和区间DP. 别人的贪心吊打我的DP,嘤嘤嘤. #include <bits/stdc++.h> #define ...
- HGOI 20190407 Typing Competition Round #1 出题记
/* ljc20020730出的HGOI20190407的模拟赛. 考试结果比预期难的不少,可能是由于本来计划5h的比赛打了4h吧. 就当普及组模拟赛好了... 难度大概4紫吧(弱省省选难度) 出境 ...
- HGOI 20190310 题解
/* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...
- [hgoi#2019/3/21]NOIP&NOI赛后总结
前言 今天做的是是2010年提高组和NOI的题目,做过几道原题,但是还是爆炸了,我真的太弱了. t1-乌龟棋 https://www.luogu.org/problemnew/show/P1541 这 ...
随机推荐
- 传统Java Web(非Spring Boot)、非Java语言项目接入Spring Cloud方案--temp
技术架构在向spring Cloud转型时,一定会有一些年代较久远的项目,代码已变成天书,这时就希望能在不大规模重构的前提下将这些传统应用接入到Spring Cloud架构体系中作为一个服务以供其它项 ...
- Vim命令使用
终端输入vim命令(不区分大小写)进入Vim,起始默认进去是normal模式(即普通模式),使用:q可以退出Vim,使用i(insert)进入编辑模式,开始输入文字,使用Esc键又可以回到normal ...
- 用python操作mysql数据库
数据库的安装和连接 PyMySQL的安装 pip install PyMySQL python连接数据库 import pymysql db = pymysql.connect("数据库ip ...
- vs nuget找不到包
nuget.org https://api.nuget.org/v3/index.json
- ARC 100 C - Linear Approximation题解---三分法
题目链接: https://arc100.contest.atcoder.jp/tasks/arc100_a 分析: 比赛时做这题想到一个瞎搞的方法就是在平均数上下波动一下取最小值,然后大佬yjw学长 ...
- JSTL标签+El表达式把list集合数据展示到 JSP页面
JSP页面 <%@ page import="cn.itcast.domain.User" %><%@ page import="java.util.L ...
- 浅析HBase:为高效的可扩展大规模分布式系统而生
什么是HBase Apache HBase是运行在Hadoop集群上的数据库.为了实现更好的可扩展性(scalability),HBase放松了对ACID(数据库的原子性,一致性,隔离性和持久性)的要 ...
- Altium Designer 编译原理图出现has no driving source警告解决办法
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 作者:struct_mooc 博客地址:https://www.cnblogs.com/stru ...
- 使用docker构建supervisor全步骤
1.使用docker build 命令基于Dockerfile文件进行构建supervisor镜像,命令:docker build -t supervisor镜像名 Dockerfile文件放置的位置 ...
- SQL SERVER 中 sp_rename 用法
转自:http://www.cnblogs.com/no7dw/archive/2010/03/04/1678287.html 因需求变更要改表的列名,平常都是跑到Enterprise manager ...