【SCOI2016】Day1 模拟
2018.8.16 8:00~11:06
先看t1,成功读错题。。。
以为是一个字符串的所有后缀都得在计划表里,否则权值就得是$n^2$
然后花了一个小时多一点写了一个错误的做法
然后没有分 才发现看错了题意
不过只要稍微改一改就行了
在近两个小时的时候过掉了第一题
然后看t2,显然的线性基+树剖,复杂度$O(n \log n \times 60 + q \log ^2 n \times 60)$
看了一下不知道能拿多少分 但是想不到更好的做法 于是就写了
获得了90分 真是不可思议
t3花了10分钟敲了一个30分暴力
总分:100+90+30
总结
感觉这一场打的没什么问题了吧
难得啊
题解
T1「SCOI2016」背单词
题面:
题解:
首先把所有字符串倒过来,把后缀变成前缀
然后建立trie树
显然的有一个性质:对于trie树上的一个结点来说,他在最终排列中的位置一定在他的所有祖先之后,所有儿子之前
因为如果不这样,出现了祖先->儿子->自己的情况,我们把儿子和自己调换位置,答案变优
然后考虑一个结点的子树
不难发现子树内部的结点一定靠在一起
因为如果不靠在一起,比如说儿子1->儿子2->儿子1的儿子1->儿子2的儿子1
我们把儿子2和儿子1的儿子1调换位置,儿子1的儿子1和儿子2的儿子1代价都减小
所以一个子树内部的结点靠在一起
最后我们确定子树之间的顺序
现在子树唯一有用的就是他的size
我们把子树设为$1~x$
最后的顺序设为$p_1~p_x$
cost就是$(1)+(1+size_{p_1})+(1+size_{p_1}+size_{p_2})+...+(1+size_{p_1}+size_{p_2}+...+size_{p_{x-1}})$
这样我们看出 应该将size按照升序排列最优
所以我们的做法就是:建立trie树,然后dfs一遍把无效结点去掉(就是那些不是终止结点的点),然后建立一个新的树(压缩之后的trie),dfs找到size,并通过size计算出每个结点的cost值(树形dp),最后dp[1]就是答案
Code:
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n;
string s[]; struct TRIE{
int cnt;
int pos[][];
int tag[];
vector<int> adj[];
ll dp[],sz[]; TRIE(){
cnt=;
} void ins(string t,int ind){
int pp=;
for(int i=;i<t.size();i++){
int nw=t[i]-'a';
if(pos[pp][nw]) pp=pos[pp][nw];
else{
cnt++;
pos[pp][nw]=cnt;
pp=cnt;
}
}
tag[pp]=ind;
} void dfs(int u,int fa=){
if(tag[u] && u!=fa) adj[fa].pb(u);
for(int i=;i<;i++){
int nw=pos[u][i];
if(nw==) continue;
if(tag[u]) dfs(nw,u);
else dfs(nw,fa);
}
} void work(int u){
vector<int> nw;
sz[u]=;
for(int i=;i<adj[u].size();i++){
int v=adj[u][i];
work(v);
nw.pb(sz[v]);
sz[u]+=sz[v];
dp[u]+=dp[v];
}
sort(nw.begin(),nw.end());
ll sum=;
for(int i=;i<nw.size();i++){
dp[u]+=sum;
sum+=nw[i];
// cout<<nw[i]<<' ';
}
//cout<<endl;
} void calc(){
work();
cout<<dp[]<<endl;
}
} trie; int main(){
// freopen("out","w",stdout);
n=read();
rep(i,,n){
cin>>s[i];
reverse(s[i].begin(),s[i].end());
trie.ins(s[i],i);
} trie.dfs();
trie.calc(); return ;
}
【SCOI2016】Day1 模拟的更多相关文章
- SCOI2016 Day1 简要题解
目录 「SCOI2016」背单词 题意 题解 代码 「SCOI2016」幸运数字 题意 题解 总结 代码 「SCOI2016」萌萌哒 题意 题解 总结 代码 「SCOI2016」背单词 题意 这出题人 ...
- 2017 五一 清北学堂 Day1模拟考试结题报告
预计分数:100+50+50 实际分数:5+50+100 =.= 多重背包 (backpack.cpp/c/pas) (1s/256M) 题目描述 提供一个背包,它最多能负载重量为W的物品. 现在给出 ...
- HGOI20180812 (NOIP2018 提高组 Day1 模拟试题)
前缀数组其实就是有序的,那么答案显然是 我们尝试求出通项公式: 证明如下: 因为 所以: 解之得: 更加通俗的写法如下: 易知 令 那么, (错位相减) 由易知等式代入得, 所以, 所以程 ...
- Day1 模拟赛 题解
T1:首先你要发现,对于任意一个奇数i,i xor (i-1)=1; 那么我们可以将答案转化为统计有多少个1相互异或起来: 所以答案就那么几种: 如果你用的数位DP,只能说明你太高估day1T1了: ...
- 纪中2018暑假培训day1提高b组改题记录
收到意见,认为每天的程序和随笔放在一起写的博客太长了,于是分开整理 day1 模拟赛,看了看提高a组t1的样例就不太想写,于是转而写b组 t1: Description 给定一个n个点m条边的有向图, ...
- 中山纪念中学培训DAY1
哇啊啊啊啊啊啊$……$ 并不像说环境怎么样. $Day1$模拟赛 稳重一点选了提高$B$ 然后$5min$后: $t1$装压$DP$最短路 $t2$裸地贪心 $t3……$哇$t3$怎么做啊啊啊啊. $ ...
- 11.2 morning
noip模拟题day1——棋盘上的问题 day1模拟题 By FancyCoder总览(Overview)注意事项:共3道题目,时间2.5小时.Pascal选手允许使用math库和ansistring ...
- NOIP2016提高组初赛(C++语言)试题 个人的胡乱分析 Part 2.
洛谷秋令营day1模拟赛原地爆炸,心态崩了.于是打算写一下初赛题放松一下. 上次胡乱分析到了选择题,这次我想说说后面的题. 问题求解 T1.有一个1x8的方格图形,黑白两色填涂每个方格,两个黑格并不能 ...
- 幸运数字(luckly)
幸运数字(luckly) 题目描述 A国共有 nn 座城市,这些城市由 TeX parse error: Misplaced & 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有 ...
随机推荐
- for in 与for of
最近在项目中需要用到遍历对象,用ES6 for of对象后报如下错误 TypeError: [object Object] is not iterable!,网上查询阮大神的教程发现“ES6 的有些 ...
- js弹出QQ对话框在线交谈
<div style="position:absolute; top:110px; right:220px; z-index:2;"> <a target=&qu ...
- 2017ACM/ICPC广西邀请赛 K- Query on A Tree trie树合并
Query on A Tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Othe ...
- Android:在子线程中更新UI的三种方式
①使用Activity中的runOnUiThread(Runnable) ②使用Handler中的post(Runnable) 在创建Handler对象时,必须先通过Context的getMainLo ...
- OO的片段,继承与组合,继承的优点与目的,虚机制在构造函数中不工作
摘自C++编程思想: ------------------------------ 继承与组合:接口的重用 ------------------------------- 继承和组合都允许由已存在的类 ...
- STM32 DMA中断只进入一次的解决办法
问题解决参见:http://bbs.ednchina.com/BLOG_ARTICLE_3014819.HTM 经过我验证,这个说的是对的.
- C/S转分布式数据库的解决方法
C/S转分布式数据库的解决方法1. 直接VPN建一个网不就行了.(大概是虚拟成一个网络)2. 直连也可以,就是速度慢3. 还是三层吧,推荐RTC4. 弄个花生壳硬件试试呢,成本低,不用改程序5. 搞一 ...
- React中Transition的作用
/** * `Transaction` creates a black box that is able to wrap any method such that * certain invarian ...
- 字典树(Trie树) C++实现
说明: 以下代码是个人按照自己的理解写的,可能有错误或者不太规范的地方,欢迎指出! 代码如下: //插入.删除.查询.遍历四种操作 //注意:四种操作的函数实现中,T都是指向上一个结点的指针,以此方便 ...
- Android API中的对话框
Android API中提供了四个Dialog的自定义子类: AlertDialog ProgressDialog DatePackerDialog TimePickerDialog 也可以派生出自己 ...