「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\)最大值是否满足要求. 然后很显然需要 ...
随机推荐
- Python3解leetcode Lowest Common Ancestor of a Binary Search Tree
问题描述: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in ...
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 GSM Base Station Identification (点在多边形内模板)
In the Personal Communication Service systems such as GSM (Global System for Mobile Communications), ...
- JS中的getter和setter
对象有两种属性:(1)数据属性,就是我们经常使用的属性(2)访问器属性,也称存取器属性 存取器属性就是一组获取和设置值的函数.getter负责获取值,它不带任何参数.setter负责设置值,在它的函数 ...
- CentOS 如何将.deb 文件 转换.rpm, centos安装deb包
CentOS 如何将.deb 文件 转换.rpm [root@localhost tmp]#tar zxvf alien_8.88.tar.gz yum install alien [root@loc ...
- 删除STL容器中的元素
有关stl容器删除元素的问题,错误的代码如下: std::vector<struct> mFriendList; ... std::vector<struct>::iterat ...
- 术语-Portal:Portal(Web站点)
ylbtech-术语-Portal:Portal(Web站点) Portal作为网关服务于因特网的一种WEB站点.Portal是链路.内容和为用户可能找到的感兴趣的信息(如新闻.天气.娱乐.商业站点. ...
- Use sed and awk to prettify json
$ cat prettify.sed s/,/,\r\n/g s/\[/\r\n\[\r\n/g s/\]/\r\n\]\r\n/g s/{/\r\n{\r\n/g s/}/\r\n}\r\n/g $ ...
- CPU的架构:x86、arm、mips、龙芯等
在公司经常听其他工程师讲x86,arm平台啥的,作为一个算法工程师,我听过却不知道这是啥!!!(汗颜) 现在偷偷学起: x86,arm,mips等这些都是CPU的架构,不管是手机电脑还是一些嵌入式的设 ...
- Robot Framework 执行结果无法查看(tomcat部署)
打开jenkins系统管理-命令行执行: System.setProperty("hudson.model.DirectoryBrowserSupport.CSP","& ...
- rope(平衡二叉树)
题目描述: 链接:https://www.nowcoder.com/acm/contest/141/C来源:牛客网 Eddy likes to play cards game since there ...