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. Coins —— POJ-1742

    Time limit 3000 ms Memory limit 30000 kB Description People in Silverland use coins.They have coins ...

  2. 用Python快速找到出现次数最多的数据

    给你一个文件,每行一个iip?

  3. Momentum Contrast for Unsupervised Visual Representation Learning

    Momentum Contrast for Unsupervised Visual Representation Learning 一.Methods Previously Proposed 1. E ...

  4. 操作系统(五)CPU调度

    CPU调度是多道程序操作系统的基础.

  5. ListVie的用法

    1.在布局中放入一个listView <ListView android:id="@+id/list_view" android:layout_width="mat ...

  6. 爬取快代理的免费IP并测试

    各大免费IP的网站的反爬手段往往是封掉在一定时间内访问过于频繁的IP,因此在爬取的时候需要设定一定的时间间隔,不过说实话,免费代理很多时候基本都不能用,可能一千个下来只有十几个可以用,而且几分钟之后估 ...

  7. 第二十三篇 jQuery 学习5 添加元素

    jQuery 学习5 添加元素   同学们,这节课,使用jQuery动态添加元素,是很关键的一课,一般用在什么地方呢:别人发表一篇文章,你评论楼主的时候,总不能是提交表单,到后台的其他页面处理,然后再 ...

  8. N1试卷常考词汇总结

    免れる まぬがれる 免去,幸免 軽率 けいそつ 轻率,草率 捩れる ねじれる 拧劲儿,扭歪,弯曲 裂ける さける 裂开,破裂 避ける さける 躲避,避开 つまむ 挟,捏,掐 追及 ついきゅう 追上.追 ...

  9. 多线程编程-- part5.1 互斥锁之公平锁-获取锁

    基本概念 1.AQS:AbstractQueuedSynchronizer类 AQS是java中管理“锁”的抽象类,锁的许多公共方法都是在这个类中实现.AQS是独占锁(例如,ReentrantLock ...

  10. commons Collections4 MultiMap

    MultiMap<String, Integer> multiMap = new MultiValueMap<>(); multiMap.put("A", ...