【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个目的地和起 ...
随机推荐
- matplotlib.pyplot import报错: ValueError: _getfullpathname: embedded null character in path
Environment: Windows 10, Anaconda 3.6 matplotlib 2.0 import matplotlib.pyplot 报错: ValueError: _getfu ...
- MCP|DYM|Quantitative mass spectrometry to interrogate proteomic heterogeneity in metastatic lung adenocarcinoma and validate a novel somatic mutation CDK12-G879V (利用定量质谱探究转移性肺腺瘤的蛋白质组异质性及验证新体细胞突变)
文献名:Quantitative mass spectrometry to interrogate proteomic heterogeneity in metastatic lung adenoca ...
- nginx丢弃http包体处理
http框架丢弃http请求包体和上一篇文章http框架接收包体, 都是由http框架提供的两个方法,供http各个模块调用,从而决定对包体做什么处理.是选择丢弃还是接收,都是由模块决定的.例如静态资 ...
- 如何使用JDBC Request跨数据库查询后引用查询的结果作为下一个JDBC Request的入参
[前言] 今天来给大家介绍下如何使用JDBC Request跨数据库查询后引用查询的结果作为下一个JDBC Request的入参! 因为我现在所测的系统模块中部分表在不同的数据库中,所以在用JDBC ...
- BufferedReader readLine
import org.apache.commons.codec.binary.Base64;import org.apache.commons.codec.digest.DigestUtils; In ...
- python入门之sys模块、shutil模块
sys模块 import sys sys.version 返回python的版本 sys.argv 返回一个以脚本名,和传入的参数作为元素的列表 sys.path 返回一个以当前代码文件路径,pyth ...
- fiddle
web开发中Chrome.IE.firefox等浏览器都自带提供了插件帮助开发者跟踪http数据,在手机客户端怎么实现http数据抓包呢?Fiddler可以实现真机调试抓包.Fiddler支持Any ...
- notepad++的tab设置为4个空格
设置--首选项--语言--制表符设置--(勾选上)替换为空格
- Hie with the Pie(poj3311)
题目链接:http://poj.org/problem?id=3311 学习博客:https://blog.csdn.net/u013480600/article/details/19692985 H ...
- POJ 1410 Intersection 数据错误
题目要求判断一条线段和一个矩形是否相交,或者是否在矩形里面(题目好像没说?) 思路就是直接暴力判断和矩形四条边是否相交,和线段的坐标是否在矩形的坐标范围即可. 然后题目的数据,(xleft,ytop) ...