[NOIP2018模拟赛10.19]只会暴力报告
闲扯
今天又是暴力满满(并不)的一天呢
昨天老师说了分数要正态分布,今天看起来...不过暴力分很多,虽然我人太傻逼又没打满
T1 woc?不是说送分的吗,看起来又是个树形DP神题,暴力告辞,链上的搞一搞
T2 woc?又是树 纪中这么喜欢出图/树题的吗?第一眼暴力dij告辞
T3 woc?又又又是树?!看起来十分码农?!部分分还好很多,想到昨天老师提到了天天爱跑步的例子,感觉可以搞一搞...于是就开始爆肝了...结果期望30分开了个fread爆0了
\(30+30+0\)凉凉,T2堆改成\(paring\)_\(heap\)就50了,辣鸡STL.虽然有一个更优的暴力...
T1 lkf
又是道神奇树形DP,分析先咕会
懒得写了,看代码注释吧...
这道题好题啊
学会两个技巧
对于差值恰为\(k\)的毒瘤限制,转化为小于等于\(k\)的限制,答案就是小于等于k的减去小于等于k-1的
对于可能重复计算的状态强制安排一个顺序,如dfs序之类的防止算重
/*
code by RyeCatcher
*/
inline char gc(){
static char buf[SIZE],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;
while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
}
const int maxn=3335;
const int inf=0x7fffffff;
const int P=19260817;
struct Edge{
int ne,to;
}edge[maxn<<1];
int h[maxn],num_edge=1;
inline void add_edge(int f,int to){
edge[++num_edge].ne=h[f];
edge[num_edge].to=to;
h[f]=num_edge;
}
int n,k,w[maxn],mx=-inf;
int id,o,lim;
ll f[maxn][maxn];
ll ans=0;
void dfs(int now,int fa){
int v;ll p=1;
//printf("%d %d\n",now,fa);
for(ri i=h[now];i;i=edge[i].ne){
v=edge[i].to;
if(v==fa)continue;
if(w[v]>=o&&w[v]<=o+lim&&(w[v]!=o||(w[v]==o&&v>id))){//前两个限制是因为状态的设计本身,第三个限制是防止联通块算重,如果还有一个点值为枚举的最小值,我们可能已经计算了那个联通块的个数
//于是我们强制安排一个顺序使得不重不漏
dfs(v,now);
p=p*(f[v][lim]+1)%P;//乘法原理,连上v贡献为f[v][lim] 否则为1
}
}
f[now][lim]=p;
return ;
}
int main(){
int x,y;
read(n),read(k);
for(ri i=1;i<=n;i++){
read(w[i]);
}
for(ri i=1;i<n;i++){
read(x),read(y);
add_edge(x,y);
add_edge(y,x);
}
for(ri i=1;i<=n;i++){
o=w[i],id=i,lim=k;
dfs(i,0);
if(k==0){
ans=(ans+f[i][k])%P;//f[i][k]表示最小值为i,最大值与最小值之差小于等于k的不同联通块
}
else{
lim=k-1;
dfs(i,0);
ans=(ans+(f[i][k]-f[i][lim])%P+P)%P;//显然f[i]][k]-f[i][k-1]即为差值刚好为k的联通块个数
}
}
printf("%lld\n",ans%P);
return 0;
}
T2 worry
有个性质就是因为你树上边随便走,你断掉一条树边后你最多走一条非树边。\(naiive\)的做法就是枚举了,有没有更高明的呢?
我们边从小到大排序,发现对于边\((x,y)\),它影响\((x,y)\)路径上的边(也就是断掉路径上的任何一条边还可以通过\((x,y)\)联通),也就是\(x,y\)分别到\(lca(x,y)\)路径上的
树链剖分
那么链剖就可以搞喽,线段树维护一个永久标记,如果有标记了也不管(因为边权从小到大排序)
跑得还挺快
/*
code by RyeCatcher
*/
inline char gc(){
static char buf[SIZE],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;
}
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;
while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
}
const int maxn=200005;
const int inf=0x7fffffff;
int n,m;
struct Edge{
int ne,to;
ll dis;
}edge[maxn<<1];
int h[maxn],num_edge=1;
inline void add_edge(int f,int to,ll c){
edge[++num_edge].ne=h[f];
edge[num_edge].to=to;
edge[num_edge].dis=c;
h[f]=num_edge;
}
pair<int,int> qwq[maxn];
struct Niconiconi{
int x,y;
ll dis;
Niconiconi(){x=y=dis=0;}
Niconiconi(int _x,int _y,ll _c){x=_x,y=_y,dis=_c;}
bool operator <(const Niconiconi &rhs)const{
return dis<rhs.dis;
}
}con[maxn<<1];
int dep[maxn],fa[maxn],son[maxn],size[maxn],top[maxn],dfn[maxn],rnk[maxn],tot=0;
void dfs1(int now){
int v;
size[now]=1;
//printf("%d %d\n",now,fa[now]);
for(ri i=h[now];i;i=edge[i].ne){
v=edge[i].to;
if(v==fa[now])continue;
dep[v]=dep[now]+1,fa[v]=now;
dfs1(v);
size[now]+=size[v];
if(!son[now]||size[son[now]]<size[v])son[now]=v;
}
return ;
}
void dfs2(int now,int t){
int v;
top[now]=t,dfn[now]=++tot,rnk[tot]=now;
if(!son[now])return ;
dfs2(son[now],t);
for(ri i=h[now];i;i=edge[i].ne){
v=edge[i].to;
if(v==fa[now]||v==son[now])continue;
dfs2(v,v);
}
return ;
}
int tag[maxn<<2],w[maxn];
int L,R,dta;
inline void pushdown(int now){
if(!tag[now<<1])tag[now<<1]=tag[now];//tag[now<<1|1]=tag[now];
if(!tag[now<<1|1])tag[now<<1|1]=tag[now];
}
void update(int now,int l,int r){
if(tag[now])return ;
if(L<=l&&r<=R){
tag[now]=dta;
return ;
}
int mid=(l+r)>>1;
pushdown(now);
if(L<=mid&&!tag[now<<1])update(now<<1,l,mid);
if(mid<R&&!tag[now<<1|1])update(now<<1|1,mid+1,r);
return ;
}
void ahaha(int now,int l,int r){
if(l==r){
if(tag[now])w[rnk[l]]=tag[now];
else w[rnk[l]]=-1;
return ;
}
int mid=(l+r)>>1;
pushdown(now);
ahaha(now<<1,l,mid);
ahaha(now<<1|1,mid+1,r);
return ;
}
inline void update_path(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])std::swap(x,y);
L=dfn[top[x]],R=dfn[x];
update(1,1,n);
x=fa[top[x]];
}
if(dep[x]>dep[y])std::swap(x,y);
L=dfn[x]+1,R=dfn[y];
//printf("--%d %d--\n",rnk[L],rnk[R]);
if(L>R)return ;
update(1,1,n);
}
int main(){
int x,y;ll z;
FO(worry);
read(n),read(m);
for(ri i=1;i<n;i++){
read(x),read(y);
add_edge(x,y,0);
add_edge(y,x,0);
qwq[i]=pair<int,int>(x,y);
}
for(ri i=1;i<=m;i++){
read(x),read(y),read(z);
con[i]=Niconiconi(x,y,z);
}
std::sort(con+1,con+1+m);
dep[1]=0,fa[1]=0;
dfs1(1);
dfs2(1,1);
memset(tag,0,sizeof(tag));
for(ri i=1;i<=m;i++){
x=con[i].x,y=con[i].y,dta=con[i].dis;
update_path(x,y);
}
ahaha(1,1,n);
for(ri i=1;i<n;i++){
x=qwq[i].first,y=qwq[i].second;
if(dep[x]<dep[y])std::swap(x,y);
printf("%d\n",w[x]);
}
return 0;
}
并查集
题解是更高明的并查集做法,我还是Too Young Too Simple,只会SB暴力树剖
每个点指向下一个没被打标记的点\(nxt[x]\)(以点代边),显然这是可传递的
这样的话每次查询直接往上跳就好了,连LCA都不用求
居然跑到rank1哈哈
/*
code by RyeCatcher
*/
inline char gc(){
static char buf[SIZE],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;
while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
}
const int maxn=100005;
const int inf=0x7fffffff;
int n,m;
struct Edge{
int ne,to;
}edge[maxn<<1];
int h[maxn],num_edge=1;
inline void add_edge(int f,int to){
edge[++num_edge].ne=h[f];
edge[num_edge].to=to;
h[f]=num_edge;
}
struct Niconiconi{
int x,y,z;
bool operator <(const Niconiconi &qwq)const{
return z<qwq.z;
}
}nico[maxn];
int ans[maxn],dep[maxn],fa[maxn],nxt[maxn],fa_id[maxn];
int get(int x){return (nxt[x]==x)?nxt[x]:nxt[x]=get(nxt[x]);}
void dfs(int now){
int v;
for(ri i=h[now];i;i=edge[i].ne){
if((v=edge[i].to)==fa[now])continue;
fa[v]=now,dep[v]=dep[now]+1,fa_id[v]=i;
dfs(v);
}
return ;
}
int main(){
int x,y,z,p;
FO(worry);
read(n),read(m);nxt[n]=n;
for(ri i=1;i<n;i++){
read(x),read(y);
add_edge(x,y),add_edge(y,x);
nxt[i]=i;
}
for(ri i=1;i<=m;i++){
read(nico[i].x),read(nico[i].y),read(nico[i].z);
}
std::sort(nico+1,nico+1+m);
fa[1]=0,dfs(1);
for(ri i=1;i<=m;i++){
x=get(nico[i].x),y=get(nico[i].y),z=nico[i].z;
while(x!=y){
if(dep[x]<dep[y])std::swap(x,y);
ans[fa_id[x]]=z;
nxt[x]=x=get(fa[x]);
}
}
p=2*n;
for(ri i=2;i<p;i+=2){
printf("%d\n",ans[i]?ans[i]:(ans[i^1]?ans[i^1]:-1));
}
return 0;
}
[NOIP2018模拟赛10.19]只会暴力报告的更多相关文章
- [NOIP2018模拟赛10.16]手残报告
[NOIP2018模拟赛10.16]手残报告 闲扯 炉石乱斗模式美滋滋啊,又颓到好晚... 上来T2先敲了树剖,看T1发现是个思博DP,然后没过大样例,写个暴力发现还是没过大样例!?才发现理解错题意了 ...
- [NOIP2018模拟赛10.25]瞎搞报告
闲扯 最近有点颓,都修到好晚,早上起来和吔shi一样难受 忍着困意把题面看完,发现啥也不会,又是一场写暴力的模拟赛 T1发现似乎可以DP,顺手码了个 T2像个最小瓶颈路板子,但是只做过N^2算法的.. ...
- [NOIP2018模拟赛10.23]发呆报告
闲扯 考场看了眼题目感觉很难,一个小时敲完了所有暴力...嗯然后就在那里发呆什么事也没做 T3考场上把数据结构想了个遍都不会完成1操作,现在看这种思路其实之前也接触过... 比较玄学的一件事情就是T1 ...
- [NOIP2018模拟赛10.22]咕咕报告
闲扯 这是篇咕咕了的博客 考场上码完暴力后不知道干什么,然后忽然发现这个T1好像有点像一道雅礼集训时讲过的CF题目 Rest In Shades ,当时那道题还想了挺久不过思路比较妙,于是我就也\(y ...
- [NOIP2018模拟赛10.18]自闭报告
闲扯 这一天,菜鸡RyeCatcher又想起来了被毒瘤题支配的恐惧 今天比较好玩,还是ljy提醒才发现文件夹里有题面...不知道外面的人什么时候才发现 看完了题面,又回到了雅礼啥题也不会写的感觉 T1 ...
- [NOIP2018模拟赛10.20A]挂分报告
闲扯 先看看了B组,T1 ZROI刚好讲过一个性质原根一般很小的,直接枚举;T2一眼二分然后似乎状压 T3没看 然后上来A组题,T1 flow这名字...网络流?! T1题面非常的社会主义核心价值观, ...
- NOIP2017提高组模拟赛 10 (总结)
NOIP2017提高组模拟赛 10 (总结) 第一题 机密信息 FJ有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的 ...
- EZ 2018 06 10 NOIP2018 模拟赛(十八)
好久没写blog&&比赛题解了,最近补一下 这次还是很狗的,T3想了很久最后竟然连并查集都忘写了,然后T2map莫名爆炸. Rating爆减......链接不解释 好了我们开始看题. ...
- EZ 2018 06 17 NOIP2018 模拟赛(十九)
这次的题目难得的水,但是由于许多哲学的原因,第二题题意表述很迷. 然后是真的猜题意了搞了. 不过这样都可以涨Rating我也是服了. Upt:链接莫名又消失了 A. 「NOIP2017模拟赛11.03 ...
随机推荐
- arcgis python获得别名
import arcpy # Create a Describe object from the GDB table. # desc = arcpy.Describe(r"C:\Users\ ...
- PLSQL 经常自动断开失去连接的解决过程
转: PLSQL 经常自动断开失去连接的解决过程 问题背景: 情况是这样的,很多开发同事的PLSQL上班时间开着8个小时,有时候他们出去抽烟后或者中午吃完饭,回来在PLSQL上面执行就报错无响应,然后 ...
- ubuntu18 faster-rcnn
luo@luo-All-Series:~/MyFile$ luo@luo-All-Series:~/MyFile$ luo@luo-All-Series:~/MyFile$ git clone htt ...
- 【作品集】UX作品集
https://www.uisdc.com/10-inspiring-ux-portfolios http://jeya.io http://antonmircea.com/FinalUX.pdf h ...
- python封装和解构
封装 将多个值使用逗号分割,组合在一起 本质上,返回一个元组,只是省略了小括号 python的特有的语法,被很多语言学习借鉴 t1 = (1,2) #定义元组 t2 = 1,2 #将1和2封装成元组 ...
- MVP模式的学习
简书: http://www.jianshu.com/p/f6fd9656f619 Github: https://github.com/tsaievan/YFMVPDemo
- WPS--world使用格式刷
1.在空白处左键点击一下即可出现格式刷
- RabbitMQ简单Java示例——生产者和消费者
添加Maven依赖: 使用rabbitmq-client的最新Maven坐标: <!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp ...
- OpenGL(5)——变换
学习三种变换:Scaling, Rotation和Translation. 上学期修了Kobbelt教授(男神!)的图形学基础课,这部分内容已经接触过. 添加GLM库,直接给出齐次坐标系下的变换矩阵和 ...
- Bean映射工具之Apache BeanUtils VS Spring BeanUtils
背景 在我们实际项目开发过程中,我们经常需要将不同的两个对象实例进行属性复制,从而基于源对象的属性信息进行后续操作,而不改变源对象的属性信息,比如DTO数据传输对象和数据对象DO,我们需要将DO对象进 ...