【HHHOJ】NOIP模拟赛 捌 解题报告
得分: \(30+30+70=130\)(弱爆了)
排名: \(Rank\ 22\)
\(Rating\):\(-31\)
\(T1\):【HHHOJ260】「NOIP模拟赛 捌」Digits(点此看题面)
比赛时写数位\(DP\)写挂了,最后交了个裸暴力。(后来发现写挂是因为没考虑借位的情况)
好吧,其实数位\(DP\)也是可以过的,但是,好像有个更简单的方法。
对于每一位,我们可以直接枚举出相加与这一位上数字相等的两个数字(总共只有\(4\)种情况),然后求解即可。
分类讨论这里就省略了,直接看代码吧:
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define uint unsigned int
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define abs(x) ((x)<0?-(x):(x))
#define INF 1e9
#define Inc(x,y) ((x+=y)>=MOD&&(x-=MOD))
#define MOD 1000000007
#define Calc1(x,y) (((i-(x)-(y))/10+1)%MOD*(tot+1)%MOD*(x)%MOD*(y)%MOD)
#define Calc2(x,y) (((i-(x)-(y))/10+1)%MOD*(tn-tot-1)%MOD*(x)%MOD*(y)%MOD)
using namespace std;
LL n;
class FIO
{
private:
#define Fsize 100000
#define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,FoutSize,stdout),Fout[(FoutSize=0)++]=ch))
LL f,FoutSize,OutputTop;char ch,Fin[Fsize],*FinNow,*FinEnd,Fout[Fsize],OutputStack[Fsize];
public:
FIO() {FinNow=FinEnd=Fin;}
inline void read(LL &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));x*=f;}
inline void read_char(char &x) {while(isspace(x=tc()));}
inline void read_string(string &x) {x="";while(isspace(ch=tc()));while(x+=ch,!isspace(ch=tc())) if(!~ch) return;}
inline void write(LL x) {if(!x) return (void)pc('0');if(x<0) pc('-'),x=-x;while(x) OutputStack[++OutputTop]=x%10+48,x/=10;while(OutputTop) pc(OutputStack[OutputTop]),--OutputTop;}
inline void write_char(char x) {pc(x);}
inline void write_string(string x) {register LL i,len=x.length();for(i=0;i<len;++i) pc(x[i]);}
inline void end() {fwrite(Fout,1,FoutSize,stdout);}
}F;
int main()
{
register LL i,j,T,ans,tn,tot,lim;F.read(T);
while(T--)
{
for(F.read(n),ans=tot=0,tn=1,i=n;i;Inc(tot,tn*(i%10)),i/=10,tn=(tn<<3)+(tn<<1))
{
if(i%10<=i) for(j=1;j<=i%10;++j) Inc(ans,Calc1(j,i%10-j));//相加与这一位相等
if(i%10-1<=i) for(j=1;j<i%10;++j) Inc(ans,Calc2(j,i%10-j-1));//相加比这一位少1,即下一位向上进位了
if(i%10+10<=i) for(j=i%10+1;j<=9;++j) Inc(ans,Calc1(j,i%10-j+10));//相加比这一位多10,即向上进一位
if(i%10+9<=i) for(j=max(i%10,1);j<=9;++j) Inc(ans,Calc2(j,i%10-j+9));//相加比这一位多9,即下一位和这一位都向上进了一位
}
F.write(ans),F.write_char('\n');//输出答案
}
return F.end(),0;
}
\(T2\):【HHHOJ261】「NOIP模拟赛 捌」Brew(点此看题面)
一道弱化版的原题: 【POJ1160】Post Office
这题就比较恶心了,考试时写了一个 暴力\(DP\) 交上去\(30\)分。
后来得知要用 \(WQS\)二分 +斜率优化\(DP\)。
应该不难发现,造的酿酒厂数量越多,答案肯定越优。
但是,如果我们给造一座酿酒厂加上一个代价\(Cost\),我们就可以发现此时的图像应该是一个单谷函数,因此就可以用斜率优化\(DP\)来求解出此时的最优答案以及最优答案对应的造酿酒厂的个数。
此时应该就不难想到 \(WQS\)二分 \(Cost\),求出 造酿酒厂个数恰好为\(K\) 时的最优答案。
代码如下:
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define uint unsigned int
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define abs(x) ((x)<0?-(x):(x))
#define INF 1e18
#define Inc(x,y) ((x+=y)>=MOD&&(x-=MOD))
#define N 100000
#define GetCost(l,r) (f[l]+GetSum((l)+1,r)+Cost)
#define Sum(l,r) (sum[r]-sum[(l)-1])
using namespace std;
LL n,m,Cost,a[N+5],sum[N+5],f[N+5],g[N+5];
class FIO
{
private:
#define Fsize 100000
#define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,FoutSize,stdout),Fout[(FoutSize=0)++]=ch))
LL f,FoutSize,OutputTop;char ch,Fin[Fsize],*FinNow,*FinEnd,Fout[Fsize],OutputStack[Fsize];
public:
FIO() {FinNow=FinEnd=Fin;}
inline void read(LL &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));x*=f;}
inline void read_char(char &x) {while(isspace(x=tc()));}
inline void read_string(string &x) {x="";while(isspace(ch=tc()));while(x+=ch,!isspace(ch=tc())) if(!~ch) return;}
inline void write(LL x) {if(!x) return (void)pc('0');if(x<0) pc('-'),x=-x;while(x) OutputStack[++OutputTop]=x%10+48,x/=10;while(OutputTop) pc(OutputStack[OutputTop]),--OutputTop;}
inline void write_char(char x) {pc(x);}
inline void write_string(string x) {register LL i,len=x.length();for(i=0;i<len;++i) pc(x[i]);}
inline void end() {fwrite(Fout,1,FoutSize,stdout);}
}F;
inline LL GetSum(LL l,LL r)
{
if(l>r) return 0;
register LL mid=l+r>>1,ln=mid-l+1,rn=r-mid+1;
return (Sum(mid,r)-rn*a[mid])+(ln*a[mid]-Sum(l,mid));
}
class Class_Monotone_queue//单调队列
{
private:
struct key
{
LL S,L,R;//L和R记录区间,S记录上次的转移点
key(LL x=0,LL y=0,LL z=0):S(x),L(y),R(z){}
}data[N+5];
LL H,T;
public:
inline void Clear() {data[H=T=1]=key(0,1,n);}//清空
inline bool empty() {return H>T;}//判断队列是否为空
inline key Front() {return data[H];}//返回队首
inline key Back() {return data[T];}//返回队尾
inline void PushBack(key x) {data[++T]=x;}//在队尾加入一个元素
inline void PopFront() {++H;}//弹出队首
inline void PopBack() {--T;}//弹出队尾
inline void Push(LL x)//加入一个新的元素
{
register LL lst=-1,l,r,mid;
while(!empty())//只要队列不为空
{
if(GetCost(data[T].S,data[T].L)>GetCost(x,data[T].L)) {lst=data[T].L,PopBack();continue;}//如果原先的斜率大于当前的斜率,就弹出队尾,并跳过当前循环
for(mid=(l=data[T].L)+(r=data[T].R)>>1;l<=r;mid=l+r>>1) GetCost(data[T].S,mid)>GetCost(x,mid)?r=mid-1:l=mid+1;//二分求出最早的从当前状态转移要优于原先状态转移的时刻
if(l<=data[T].R) data[T].R=(lst=l)-1;//更新
break;//退出循环
}
if(~lst) PushBack(key(x,lst,n));//如果有值,将其加入队列
if(!empty()&&++data[H].L>data[H].R) PopFront();//如果队首所表示区间为空,则将其弹出
}
}q;
inline bool check(LL C)//求出额外代价为C时的最优答案以及对应造酿酒厂的个数是否小于等于m
{
Cost=C,q.Clear();//清空数组
for(register LL i=1;i<=n;++i)//斜率优化DP
f[i]=GetCost(q.Front().S,i),g[i]=g[q.Front().S]+1,q.Push(i);//计算出最优答案以及对应造酿酒厂的个数,然后将当前的i加入单调队列
return g[n]<=m;//如果g[n]≤m则返回true
}
int main()
{
register LL i,j,l,r,mid;
for(F.read(n),F.read(m),i=1;i<=n;++i) F.read(a[i]);
for(sort(a+1,a+n+1),i=1;i<=n;++i) sum[i]=sum[i-1]+a[i];
for(mid=(l=0)+(r=INF)>>1;l<=r;mid=l+r>>1) check(mid)?r=mid-1:l=mid+1;//WQS二分
return check(l),F.write(f[n]-l*m),F.end(),0;//输出答案
}
\(T3\):【HHHOJ262】「NOIP模拟赛 捌」QTree(点此看题面)
先吐槽一波比赛时的数据太水(虽然我懒得优化暴力,结果还是没过)。
现在数据加强了,我本来改完能过的暴力代码现在被一个类似于菊花图的东西给卡崩了。
暴力我觉得就不用多讲了,大不了就是直接暴力修改+询问。
唯一要注意的地方应该是关于\(vis\)数组的清空,我比较建议记录一下每次操作的编号,这样就可以不用清空数组,起到了极大程度的优化。
还是谈一谈正解吧(虽然我还没过),正解的大致思路是将节点的\(BFS\)序存下来,然后用一棵线段树维护。
听起来好像并不难的样子。
但是,考虑到这是一棵基环外向树,听说无论什么题目一套上一个基环外向树就会码量大增... ...
看了一下\(AC\)代码,\(4.0kb\)起步,顿时失去了打的勇气... ...
代码以后再补吧。
【HHHOJ】NOIP模拟赛 捌 解题报告的更多相关文章
- 【HHHOJ】NOIP模拟赛 玖 解题报告
点此进入比赛 得分: \(100+20+100=220\)(还不错) 排名: \(Rank\ 16\) \(Rating\):\(+20\) \(T1\):[HHHOJ263]「NOIP模拟赛 玖」三 ...
- 20161005 NOIP 模拟赛 T2 解题报告
beautiful 2.1 题目描述 一个长度为 n 的序列,对于每个位置 i 的数 ai 都有一个优美值,其定义是:找到序列中最 长的一段 [l, r],满足 l ≤ i ≤ r,且 [l, r] ...
- CH Round #55 - Streaming #6 (NOIP模拟赛day2)解题报告
T1九九归一 描述 萌蛋在练习模n意义下的乘法时发现,总有一些数,在自乘若干次以后,会变成1.例如n=7,那么5×5 mod 7=4,4×5 mod 7=6,6×5 mod 7=2,2×5 mod 7 ...
- CH Round #54 - Streaming #5 (NOIP模拟赛Day1)解题报告
最近参加了很多CH上的比赛呢~Rating--了..题目各种跪烂.各种膜拜大神OTZZZ T1珠 描述 萌蛋有n颗珠子,每一颗珠子都写有一个数字.萌蛋把它们用线串成了环.我们称一个数字串是有趣的,当且 ...
- 20161007 NOIP 模拟赛 T1 解题报告
排序 3.1 题意描述 众所周知,熟练掌握至少一种排序算法是参加NOIP的必备技能.常见的排序算法有冒泡 排序.归并排序.快速排序.奇偶排序.猴子排序.梳排序.鸡尾酒排序.臭皮匠排序等. 在这里,介绍 ...
- 20161003 NOIP 模拟赛 T2 解题报告
Weed duyege的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹. 为了查出真相,duyege 准备修好电脑之后再进行一次金坷垃的模拟实验. 电脑上面有若干层金坷垃,每次只能在上面撒上一层高度为 ...
- 20161005 NOIP 模拟赛 T3 解题报告
subset 3.1 题目描述 一开始你有一个空集,集合可以出现重复元素,然后有 Q 个操作 1. add s 在集合中加入数字 s. 2. del s 在集合中删除数字 s.保证 s 存在 3. c ...
- 【BLUESKY的NOIp模拟赛】解题报告
昨天晚上熬夜熬得有点严重,今天比赛的时候状态不好,成绩爆炸... 不得不说BLUESKY007 出的题还是相当不错的,也为我提醒了几个需要补的漏洞方向,这里作一下整理. \(Task 1\):探索 ...
- 20161022 NOIP模拟赛 T1 解题报告
旅行者问题 [问题描述] lahub是一个旅行者的粉丝,他想成为一个真正的旅行者,所以他计划开始一段旅行.lahub想去参观n个目的地(都在一条直道上).lahub在起点开始他的旅行.第i个目的地和起 ...
随机推荐
- python 变量,输入,输出
目录 2.0 注释 2.1 变量 2.2 变量名命名规范 2.3 常量 2.4 输入 input 2.5 输出 print 2.6 关于开发工具 2.0 注释 python的注释方法 "&q ...
- jsp页面将日期类型的数据转换成xxxx年xx月xx日xx时xx分
<fmt:formatDate value="${bsjz.cxkssj}" pattern="yyyy"/><span class=&quo ...
- Maven的相关知识及使用
一.简介 maven: 是apache下的一个开源项目,是纯java开发,并且只是用来管理java项目的,Maven是跨平台的项目管理工具. 1.自动化构建和项目管理工具 Ant→Make→Maven ...
- P3379 【模板】最近公共祖先(LCA)(倍增)
这题有毒!!!!!!!!!! TM我重新打的板子,然而...... 5分钟打完 debug两小时 我的写法常数太大了 每次DFS都要For去更新F 最后写了快读才A 改: 只处理f[i][0] dfs ...
- 原生DOM操作方法小结
1.0 DOM结构 父节点 兄弟节点 当前节点 属性节点 子节点 兄弟节点 一般任意一个节点我们都会从父节点,子节点,以及兄弟节点的角度去考察.节点一般我们只需关注元素节点,属性节点及文本节点即可 ...
- 配置IIS Web服务器
配置IIS Web服务器 1.1 控制面板中找到“程序”并打开 1.2 程序界面找到“启用或关闭Windows功能”并打开 1.3 上面两步也可以简化为一步:按[Win + R]快捷键打开运行对话框, ...
- Java面向对象_数据结构之链表
链表:是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里村到下一个节点的指针. 在链表数据结构中,需要使用到递归算法.递归算法是一种直接或间接地调用自身算法的过 ...
- VMWare复制虚拟机系统后,模块“Disk”无法启动【转】
1.找到虚拟机所在的目录 将 .vmx文件打开 将文件vmci0.present = "TRUE" 改为 vmci0.present = "FALSE" 2.删 ...
- java CountDownLatch 等待多线程完成
CountDownLatch允许一个或多个线程等待其他线程完成操作. package com.test; import java.util.concurrent.CountDownLatch; pub ...
- SpringBoot | 第二十一章:异步开发之异步调用
前言 上一章节,我们知道了如何进行异步请求的处理.除了异步请求,一般上我们用的比较多的应该是异步调用.通常在开发过程中,会遇到一个方法是和实际业务无关的,没有紧密性的.比如记录日志信息等业务.这个时候 ...