「NOI2017」整数 解题报告
「NOI2017」整数
有一些比较简单的\(\log^2n\)做法
比如暴力在动态开点线段树上维护每个位置为\(0\)还是\(1\),我们发现涉及到某一位加上\(1\)或者减去\(1\)实际上对其他位的影响只有区间覆盖,通过线段树上二分可以得到区间覆盖的位置,然后暴力区间覆盖即可。
反正我这种菜鸡大常数写法只得到了68分..
考虑利用势能,注意到如果同时改变加法和减法,势能很容易被\(b\)搞掉
如果分开维护加法和减法,把位置上的\(1\)的个数当做势能,可以发现,暴力修改是均摊\(O(n\log a)\)的
直接暴力维护两个数组\(plu\)和\(dec\)
考虑单点求值,因为保证了\(x\ge 0\)
所以我们发现只需要两个条件就可以确定第\(k\)位的值,即
- \(ans_1=[plu_k=dec_k]\)
- \(ans_2=[plu[k-1,1]\ge[dec[k-1,1]]]\),这里是倒着进行字符串比较的意思
第\(k\)位的答案即为\(ans_1 \ xor \ ans_2\),这里讨论一下就可以得到了
考虑找到\(\le p\)位置的两个数组第一个不同的位置,然后比较大小
一个暴力的想法是,把每个不同的位置塞到set里面去,然后每次在set里面二分找一下位置,也是\(\log^2n\)的
考虑到每次修改的一个长为\(\log a\)连续的区间(这里实际上饶了一个大圈子)
所以把区间每\(\log a\)分一块,块也是有势能的,然后set里面一次赛一个块就可以了
复杂度就一个\(\log\)了
Code:
#include <cstdio>
#include <cctype>
#include <set>
#include <algorithm>
#define ll long long
using std::min;
const int SIZE=1<<21;
char ibuf[SIZE],*iS,*iT;
//#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
#define gc() getchar()
template <class T>
void read(T &x)
{
int f=0;x=0;char c=gc();
while(!isdigit(c)) f|=c=='-',c=gc();
while(isdigit(c)) x=x*10+c-'0',c=gc();
if(f) x=-x;
}
const int N=1e6+10;
int n,t1,t2,t3;
int plu[N*30],dec[N*30],bel[N*30];
int edt[N],vis[N];
std::set <int> s;
std::set <int>::iterator it;
int qry(int p)
{
while(p%32!=0&&plu[p]==dec[p]) --p;
if(plu[p]!=dec[p])
{
if(plu[p]>dec[p]) return 1;
else return 0;
}
p=bel[p];
it=s.upper_bound(p);
if(s.empty()||it==s.begin()) return 1;
--it;
p=(*it)*32;
while(plu[p]==dec[p]) --p;
if(plu[p]>dec[p]) return 1;
else return 0;
}
int main()
{
read(n),read(t1),read(t2),read(t3);
int m=n*30+31,T=(m-1)/32+1;
for(int L,R=0,i=1;i<=T;i++)
{
L=R+1,R=i*32;
for(int j=L;j<=R;j++) bel[j]=i;
}
for(int op,a,b,k,i=1;i<=n;i++)
{
read(op);
if(op==1)
{
edt[0]=0;
read(a),read(b);
if(a>0)
{
for(int p,j=1;j<=30;j++)
if(a>>j-1&1)
{
p=j+b;
if(vis[bel[p]]!=i)
edt[++edt[0]]=bel[p],vis[bel[p]]=i;
while(plu[p])
{
plu[p++]=0;
if(vis[bel[p]]!=i)
edt[++edt[0]]=bel[p],vis[bel[p]]=i;
}
plu[p]=1;
}
}
else
{
a=-a;
for(int p,j=1;j<=30;j++)
if(a>>j-1&1)
{
p=j+b;
if(vis[bel[p]]!=i)
edt[++edt[0]]=bel[p],vis[bel[p]]=i;
while(dec[p])
{
dec[p++]=0;
if(vis[dec[p]]!=i)
edt[++edt[0]]=bel[p],vis[bel[p]]=i;
}
dec[p]=1;
}
}
for(int j=1;j<=edt[0];j++)
{
int L=(edt[j]-1)*32+1,R=edt[j]*32,flag=1;
for(int l=L;l<=R;l++)
if(plu[l]!=dec[l])
{
flag=0;
break;
}
if(flag)
{
if(s.find(edt[j])!=s.end()) s.erase(edt[j]);
}
else
s.insert(edt[j]);
}
}
else
{
read(k);
int p=k++;
int ans=0;
if(plu[k]==dec[k]) ans=1;
printf("%d\n",ans^qry(p));
}
}
return 0;
}
2019.5.31
「NOI2017」整数 解题报告的更多相关文章
- 「NOI2017」蔬菜 解题报告
「NOI2017」蔬菜 首先考虑流 可以从 \(s\) 流入表示得到蔬菜,流出到 \(t\) 表示卖出蔬菜,给每个蔬菜拆点,并给它它每天应得的蔬菜. 但是我们没办法直接给,注意到如果把变质看成得到并可 ...
- 「NOI2017」游戏 解题报告
「NOI2017」游戏 \(d\)这么小,你考虑直接对\(d\)个东西暴力 枚举\(x\)为\(a\)或\(b\)(\(c\)就不用了,因为\(a,b\)已经包含\(c\))了,剩下的就是个\(2-s ...
- LibreOJ2302 - 「NOI2017」整数
Portal Description 有一个整数\(x=0\),对其进行\(n(n\leq10^6)\)次操作: 给出\(a(|a|\leq10^9),b(b\leq30n)\),将\(x\)加上\( ...
- 「ZJOI2016」旅行者 解题报告
「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...
- 「HNOI2016」树 解题报告
「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...
- 「HNOI2016」序列 解题报告
「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...
- 「HNOI2016」网络 解题报告
「HNOI2016」网络 我有一个绝妙的可持久化树套树思路,可惜的是,它的空间是\(n\log^2 n\)的... 注意到对一个询问,我们可以二分答案 然后统计经过这个点大于当前答案的路径条数,如果这 ...
- 「HAOI2018」染色 解题报告
「HAOI2018」染色 是个套路题.. 考虑容斥 则恰好为\(k\)个颜色恰好为\(c\)次的贡献为 \[ \binom{m}{k}\sum_{i\ge k}(-1)^{i-k}\binom{m-k ...
- 「HNOI2016」最小公倍数 解题报告
「HNOI2016」最小公倍数 考虑暴力,对每个询问,处理出\(\le a,\le b\)的与询问点在一起的联通块,然后判断是否是一个联通块,且联通块\(a,b\)最大值是否满足要求. 然后很显然需要 ...
随机推荐
- ssm框架错误展示-1
1.xmlParse错误+找不到bean ,一般会出现在导入别的地方拷来的项目时发生,报了以下错误: 查看自己的项目配置文件,发现spring的配置文件和sql映射xml文件都有个黄颜色的感叹号,鼠标 ...
- 10.18.1 linux文本编辑器vim
vi和vim的区别 编辑一个文本时,vi不会显示颜色,而vim会显示颜色,vi 有点类似windows记事本,简单,那么就是vim复杂编辑器,功能复杂,高亮,自动缩进(写shell/python脚本用 ...
- The Tree-planting Day and Simple Disjoint Sets
First I have to say: I have poor English. I am too young, too simple, sometimes naïve. It was tree-p ...
- 转载:IDEA配置SVN及使用
转自:https://blog.csdn.net/zwj1030711290/article/details/80687365 1.安装svn客户端 之前用myEcplise只需要插件,现在IDEA需 ...
- CSS布局浮动和定位属性的区别
float: left|right; 可以自动排列自动折行, 但需要clear来配合清除浮动;display: inline-block 有些时候可以替代float实现相同的效果. position: ...
- socket 接收和发送缓冲区
问题产生: 在进行客户端向服务端发送数据时,每次发送一定数量数据后发送端就等不到send函数的返回,导致程序一直卡死在send函数. 通过抓包发现:发送端发送过快而接收端处理速度过慢,导致快速发送一定 ...
- jmeter添加自定义扩展函数之String---base64加密
1,打开eclipse,新建maven工程,在pom中引用jmeter核心jar包,具体请看---https://www.cnblogs.com/guanyf/p/10863033.html---,这 ...
- crontab 使用
1. 安装,结构 yum install cronie 结构: * * * * * [分钟] [小时] [每月的某一天] [每年的某一月] [每周的某一天] 2.命令 1,添加或更新crontab中的 ...
- Selenium:火狐Try Xpath插件替代Firebug和Firepath
什么是Xpath? XPath是XML的路径语言,通俗一点讲就是通过元素的路径来查找到这个标签元素. 工具 Xpath的练习建议大家安装火狐浏览器后,下载插件,try path. 在Selenium中 ...
- selenium快捷键操作
常用的键盘操作 send_keys(Keys.BACK_SPACE) 删除键(BackSpace) send_keys(Keys.SPACE) 空格键(Space) send_keys(Keys.TA ...