题目大意:
  给你一个数列,问区间[l,r]内与k最接近的数与k的差是多少。

思路:
  将数列中的数和询问的数先从小到大排序,
  从小到大枚举每个数,如果是数列上的,就加到线段树中,
  如果是询问中的,就在线段树上查找区间最大值,
  这样就找到了区间中小于等于这个数的最大值。
  反过来也一样。
  一个最大值、一个最小值,对于询问的数作差,取min即可。
  比原来的主席树算法不知道妙到哪里去了。
  主席树加了离散化以后应该能过,不过我的程序一直没过,然而虞皓翔同样是主席树的程序可以随便过。
  大概是我写得比较烂吧。

 #include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
#include<functional> inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
} const int inf=0x7fffffff;
const int N=; struct Num {
int val,pos,l,r,id;
bool operator < (const Num &another) const {
if(val<another.val) return true;
if(val>another.val) return false;
return pos;
}
bool operator > (const Num &another) const {
if(val>another.val) return true;
if(val<another.val) return false;
return pos;
}
};
std::vector<Num> v; class SegmentTree {
#define _left <<1
#define _right <<1|1
private:
int val[N<<];
void push_up(const int &p,const bool &cmp) {
val[p]=cmp?std::max(val[p _left],val[p _right]):std::min(val[p _left],val[p _right]);
}
public:
void reset(const int &x) {
std::fill(&val[],&val[N<<],x);
}
void modify(const int &p,const int &b,const int &e,const int &x,const int &v,const bool &cmp) {
if(b==e) {
val[p]=v;
return;
}
const int mid=(b+e)>>;
if(x<=mid) modify(p _left,b,mid,x,v,cmp);
if(x>mid) modify(p _right,mid+,e,x,v,cmp);
push_up(p,cmp);
}
int query(const int &p,const int &b,const int &e,const int &l,const int &r,const bool &cmp) {
if(b==l&&e==r) {
return val[p];
}
const int mid=(b+e)>>;
int ret=cmp?-:inf;
if(l<=mid) ret=cmp?std::max(ret,query(p _left,b,mid,l,std::min(mid,r),cmp)):std::min(ret,query(p _left,b,mid,l,std::min(mid,r),cmp));
if(r>mid) ret=cmp?std::max(ret,query(p _right,mid+,e,std::max(mid+,l),r,cmp)):std::min(ret,query(p _right,mid+,e,std::max(mid+,l),r,cmp));
return ret;
}
#undef _left
#undef _right
};
SegmentTree t; int ans[N]; int main() {
int T=getint();
for(register int i=;i<=T;i++) {
printf("Case #%d:\n",i);
const int n=getint(),q=getint();
v.clear();
for(register int i=;i<=n;i++) {
v.push_back((Num){getint(),i,,,});
}
for(register int i=;i<q;i++) {
const int l=getint(),r=getint(),k=getint();
v.push_back((Num){k,,l,r,i});
}
std::fill(&ans[],&ans[q],inf);
t.reset(-);
std::sort(v.begin(),v.end(),std::less<Num>());
for(register std::vector<Num>::iterator it=v.begin();it!=v.end();it++) {
if(it->pos) {
t.modify(,,n,it->pos,it->val,true);
} else {
const int tmp=t.query(,,n,it->l,it->r,true);
if(tmp!=-) ans[it->id]=std::min(ans[it->id],std::abs(tmp-it->val));
}
}
t.reset(inf);
std::sort(v.begin(),v.end(),std::greater<Num>());
for(register std::vector<Num>::iterator it=v.begin();it!=v.end();it++) {
if(it->pos) {
t.modify(,,n,it->pos,it->val,false);
} else {
const int tmp=t.query(,,n,it->l,it->r,false);
if(tmp!=inf) ans[it->id]=std::min(ans[it->id],std::abs(tmp-it->val));
}
}
for(register int i=;i<q;i++) {
printf("%d\n",ans[i]);
}
}
return ;
}

原来也写过一个主席树的写法,然而复杂度不是很优秀,一直过不了。

 #include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int inf=0x7fffffff;
const int N=;
int size;
class FotileTree {
private:
struct Node {
int left,right,val;
};
Node nd[N*];
int sz,newNode(const int &p) {
sz++;
nd[sz]=nd[p];
return sz;
}
public:
int root[N];
void reset() {
sz=;
}
int modify(const int &p,const int &b,const int &e,const int &x) {
int new_p=newNode(p);
nd[new_p].val++;
if(b==e) return new_p;
const int mid=(b+e)>>;
if(x<=mid) nd[new_p].left=modify(nd[p].left,b,mid,x);
if(x>mid) nd[new_p].right=modify(nd[p].right,mid+,e,x);
return new_p;
}
int queryleq(const int &p1,const int &p2,const int &b,const int &e,const int &x) const {
if(!(nd[p2].val-nd[p1].val)) return size-;
if(b==e) return e;
const int mid=(b+e)>>;
if(x<=mid) return queryleq(nd[p1].left,nd[p2].left,b,mid,x);
int ret;
if((ret=queryleq(nd[p1].right,nd[p2].right,mid+,e,x))!=size-) return ret;
if((ret=queryleq(nd[p1].left,nd[p2].left,b,mid,x))!=size-) return ret;
return size-;
}
int querygeq(const int &p1,const int &p2,const int &b,const int &e,const int &x) const {
if(!(nd[p2].val-nd[p1].val)) return size-;
if(b==e) return b;
const int mid=(b+e)>>;
if(x>mid) return querygeq(nd[p1].right,nd[p2].right,mid+,e,x);
int ret;
if((ret=querygeq(nd[p1].left,nd[p2].left,b,mid,x))!=size-) return ret;
if((ret=querygeq(nd[p1].right,nd[p2].right,mid+,e,x))!=size-) return ret;
return size-;
}
};
FotileTree t;
int a[N],l[N],r[N],x[N],b[N+N];
int main() {
int T=getint();
for(register int i=;i<=T;i++) {
printf("Case #%d:\n",i);
const int n=getint(),q=getint();
b[]=inf;
for(register int i=;i<=n;i++) {
b[i]=a[i]=getint();
}
for(register int i=;i<=q;i++) {
l[i]=getint();
r[i]=getint();
b[n+i]=x[i]=getint();
}
std::sort(&b[],&b[n+q+]);
size=std::unique(&b[],&b[n+q+])-b;
for(register int i=;i<=n;i++) {
const int id=std::lower_bound(&b[],&b[size],a[i])-b;
t.root[i]=t.modify(t.root[i-],,size-,id);
}
for(register int i=;i<=q;i++) {
const int id=std::lower_bound(&b[],&b[size],x[i])-b;
const int leq=b[t.queryleq(t.root[l[i]-],t.root[r[i]],,size-,id)];
const int geq=b[t.querygeq(t.root[l[i]-],t.root[r[i]],,size-,id)];
printf("%d\n",std::min(std::abs(x[i]-leq),std::abs(x[i]-geq)));
}
}
return ;
}

[HihoCoder1169]猜单词的更多相关文章

  1. python 游戏(猜单词Hangman)

    1.游戏思路和流程图 实现功能:随机一个单词让玩家猜测(后续难度实现修改为成语填空,成语必须要有提示,可修改猜的次数,增加连续猜成语,难度系数随着次数的增加而增加) 游戏流程图 2. 单词库和模块 i ...

  2. 关于切片/截取(slice)和random模块的使用(实例:猜单词小游戏)

    切片和random的使用在源码中都有注释(可以直接下载):https://github.com/NoobZeng/GuessWords 1. README.MD 基于Python的猜单词游戏 猜单词小 ...

  3. Python小游戏 -- 猜单词

    Python初学者小游戏:猜单词 游戏逻辑:就像我们曾经英语学习机上的小游戏一样,电脑会从事先预置的词库中抽取单词,然后给出单词的字母数量,给定猜解次数,然后让玩家进行猜测,并给出每次猜测的正确字母与 ...

  4. [LeetCode] 843. Guess the Word 猜单词

    This problem is an interactive problem new to the LeetCode platform. We are given a word list of uni ...

  5. [Swift]LeetCode843. 猜猜这个单词 | Guess the Word

    This problem is an interactive problem new to the LeetCode platform. We are given a word list of uni ...

  6. 任务驱动,学习.NET开发系列第2篇------单词统计

    一 高效学习编程的办法 1 任务驱动方式学习软件开发 大部分人学习软件开发技术是通过看书,看视频,听老师上课的方式.这些方式有一个共同点即按知识点进行讲解.比如拿c#编程为例,首先是讲解大量的基础概念 ...

  7. python练手项目

    文本操作 逆转字符串--输入一个字符串,将其逆转并输出. 拉丁猪文字游戏--这是一个英语语言游戏.基本规则是将一个英语单词的第一个辅音音素的字母移动到词尾并且加上后缀-ay(譬如"banan ...

  8. 【C++】命令行Hangman #2015年12月15日 00:20:27

    增加了可以在构造Hangman对象时通过传入参数设定“最大猜测次数”的功能.少量修改.# 2015年12月15日 00:20:22 https://github.com/shalliestera/ha ...

  9. cryptography

    密码关还是有很多变态的题的,整理一下力所能及的吧. Circular Crypto(Asis-CTF2013) 这题只给了一张图片 仔细看一下就知道,这是几个单独的环,把它们分别整理出来.因为看着眼花 ...

随机推荐

  1. 2017 ACM暑期多校联合训练 - Team 4 1012 HDU 6078 Wavel Sequence (模拟)

    题目链接 Problem Description Have you ever seen the wave? It's a wonderful view of nature. Little Q is a ...

  2. CSS 中 nth-child 和 nth-of-type 的区别

    假设有如下代码结构,想要查找 Piggy 那个 p <section> <h1>Words</h1> <p>Little</p> <p ...

  3. sqlmap的使用方法 ——时光凉春衫薄

    普通注入 Sqlmap -u “http://www.xxxxxx.com/xxxx/xxx/xxx.xxx?xx=xx” --dbs 找到一个sql的注入点 探测他的库名   access的直接探表 ...

  4. 64_o1

    OCE-devel-0.18.1-1.fc26.i686.rpm 15-May-2017 18:37 5634474 OCE-devel-0.18.1-1.fc26.x86_64.rpm 15-May ...

  5. elk系列6之tcp模块的使用【转】

    preface tcp模块的使用场景如下: 有一台服务器A只需要收集一个日志,那么我们就可以不需要在这服务器上安装logstash,我们通过在其他logstash上启用tcp模块,监听某个端口,然后我 ...

  6. 挂载cifs报错mount error(13): Permission denied(域账号访问时报错)

    Linux挂载Windows共享时,报以下错误: mount error(13): Permission deniedRefer to the mount.cifs(8) manual page (e ...

  7. iTextSharp操作pdf之pdfCreater

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. Python如何实现文本转语音

    准备 我测试使用的Python版本为2.7.10,如果你的版本是Python3.5的话,这里就不太适合了. 使用Speech API 原理 我们的想法是借助微软的语音接口,所以我们肯定是要进行调用 相 ...

  9. google浏览器中,使用clockwork 来调试

    参考:https://laravel-china.org/courses/laravel-package/1976/debugging-tool-under-chrome-itsgoingdclock ...

  10. MySql学习笔记——存储函数

    在学习完存储过程后,今天主要回顾一下mysql中的存储函数的知识. 函数与存储过程的区别 首先,存储函数也是过程式对象之一,与存储过程相似.它们都是由SQL和过程式语句组成的代码片断,并且可以从应用程 ...