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>表示不能的到达的点。

转移:

\[f_{i,j,k,l,n,m} = f_{i-1,j,k,l,m,n} + f_{i,j-1,k,l,m,n} + f_{i,j,k-1,l,m,n} + f_{i,j,k,l-1,m,n} + f_{i,j,k,l,m-1,n} + f_{i,j,k,l,m,n-1}
\]

注意到 \(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\)。

所以答案为

\[\mathrm{ans} = \sum_{i,j \in A} [T(i + j) \mod 2 = 1] \\
= \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的更多相关文章

  1. HGOI 20191106 题解

    Problem A  旅行者 有$n$种转移装置,每种转移装置本质相同,每种装置可以前进$a_i$单位,但只有$b_i$个. 从初始坐标为$0$出发,途中不能经过$c_1,c2,...,c_m$中的任 ...

  2. HGOI 20181028 题解

    HGOI 20181028(复赛备考) /* 真是暴力的一天,最后一题MLE?由于数组开得太大了!!! 270滚粗 考场上好像智商高了很多?!(假的) */ sol:暴力求解,然后没有数据范围吐槽一下 ...

  3. HGOI NOIP模拟4 题解

    NOIP国庆模拟赛Day5 题解 T1 马里奥 题目描述 马里奥将要参加 NOIP 了,他现在在一片大陆上,这个大陆上有着许多浮空岛,并且其中一座浮空岛上有一个传送门,马里奥想要到达传送门从而前往 N ...

  4. [20191106]善用column格式化输出.txt

    [20191106]善用column格式化输出.txt # man columnDESCRIPTION     The column utility formats its input into mu ...

  5. GoCN每日新闻(2019-11-06)

    GoCN每日新闻(2019-11-06) GoCN每日新闻(2019-11-06) 1. 使用构建标签分离你的测试文件 https://mickey.dev/posts/go-build-tags-t ...

  6. 「HGOI#2019.4.19省选模拟赛」赛后总结

    t1-Painting 这道题目比较简单,但是我比较弱就只是写了一个链表合并和区间DP. 别人的贪心吊打我的DP,嘤嘤嘤. #include <bits/stdc++.h> #define ...

  7. HGOI 20190407 Typing Competition Round #1 出题记

    /* ljc20020730出的HGOI20190407的模拟赛. 考试结果比预期难的不少,可能是由于本来计划5h的比赛打了4h吧. 就当普及组模拟赛好了... 难度大概4紫吧(弱省省选难度) 出境 ...

  8. HGOI 20190310 题解

    /* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...

  9. [hgoi#2019/3/21]NOIP&NOI赛后总结

    前言 今天做的是是2010年提高组和NOI的题目,做过几道原题,但是还是爆炸了,我真的太弱了. t1-乌龟棋 https://www.luogu.org/problemnew/show/P1541 这 ...

随机推荐

  1. PHP空对象 空数组

    PHP定义空对象:$obj = (object)null;或$obj = (object)array(); 定义空数组:$arr = array();或$arr = [];//自 5.4 起可以使用短 ...

  2. 使用antd List组件实现轮播图

    import { List, Avatar, Carousel } from 'antd'; import { connect } from 'dva'; import './lamp.less' c ...

  3. sed---流文本操作

    一:sed基本命令 sed的使用格式 sed [optiona] 'command' files sed 参数[-nefir] 动作[n1,[n2]] function sed -n:只有经过sed特 ...

  4. C数据结构排序算法——希尔排序法用法总结(转http://www.cnblogs.com/skywang12345/p/3597597.html)

    希尔排序介绍 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进.该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 希尔排序实质上是一种分组插入方法.它 ...

  5. 面向对象-this关键字的概述和应用

    /* 我们曾经说过:定义名字要做到见名知意. this:是当前类的对象引用.简单的记,它就代表当前类的一个对象. 注意:谁调用这个方法,在该方法内部的this就代表谁. this的场景: 解决局部变量 ...

  6. 多线程编程-- part5 锁的种类以及辨析

    java中的锁,可以分为同步锁和JUC包中的锁. 同步锁 通过synchronized关键字进行同步,实现对竞争资源的互斥访问的锁,. 原理:对于每一个对象,有且只有一个同步锁,在同一时间点,所有的线 ...

  7. Linux上ssh免秘钥互登

    两台机器分别为:master:192.168.1.10sever1:192.168.1.20 1.检查机器名和连通性 a.查看/etc/hostname [root@master master]# m ...

  8. .Net Framework4.5中Asp.net mvc使用Singal R轮训实现导入进度条功能

    .Net Framework4.5中Asp.net mvc使用Singal R轮训实现导入进度条功能 我的项目需求是:在.net4.5中用mvc5实现上传xml文件,后台实时导入数据库时传到前台进度, ...

  9. HttpClient 释放连接

    Release the Connection:释放连接 This is a crucial step to keep things flowing. We must tell HttpClient t ...

  10. 文件I/O简述

    什么是I/O 宏观上讲,I/O是信息处理系统(例如计算机)与外部世界(可能是人或其他信息处理系统)之间的通信.输入(Input)是系统接收的信号或数据,输出(Output)是从其发送的信号或数据.另一 ...