• [SHOI2013]发牌 解题报告


    [SHOI2013]发牌

    题意

    对一个(1sim n(nle 7 imes 10^5))的环,指标最开始在(1),每次删去顺时针往后第(d_i)个元素,指标移到下一个位置。要求输出每次删去元素的标号。


    看了沙茶数据范围,我就放弃了平衡树,毕竟我这种人丑常数大的选手?

    然后开始思考线段树或者树状数组,yy了好一会儿才想出一个沙茶的做法,写了以后发现题解好像没有我这么写的,就来口胡一下。

    在线段树上维护每个点左边还有多少个元素存在。

    每次询问的时候,有一个上次开始的删去的位置(s)(初始为(0)),然后统计一下(s)前面有多少个元素,判断这次删掉的是在(s)左边还是右边。

    假设每次输入的是(d),如果在(s)左边,就(d-)右边元素个数,在右边就(d+)左边元素个数,然后直接在线段树上二分找就可以了。


    Code:

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    using std::max;
    const int N=7e5+10;
    int read()
    {
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    int sum[N],n,s;
    void add(int x){while(x<=n)++sum[x],x+=x&-x;}
    int ask(int x){int ret=0;while(x)ret+=sum[x],x-=x&-x;return ret;}
    int mx[N<<2],tag[N<<2];
    #define ls id<<1
    #define rs id<<1|1
    void build(int id,int l,int r)
    {
    	mx[id]=r;
    	if(l==r)return;
    	int mid=l+r>>1;
    	build(ls,l,mid),build(rs,mid+1,r);
    }
    void pushdown(int id)
    {
    	if(tag[id])
    	{
    		mx[ls]+=tag[id],mx[rs]+=tag[id];
    		tag[ls]+=tag[id],tag[rs]+=tag[id];
    		tag[id]=0;
    	}
    }
    void query(int id,int l,int r,int k)
    {
    	if(l==r) {printf("%d
    ",s=l),mx[id]=0,add(l);return;}
    	pushdown(id);
    	int mid=l+r>>1;
    	if(mx[ls]>=k) query(ls,l,mid,k);
    	else query(rs,mid+1,r,k);
    }
    void change(int id,int l,int r,int p)
    {
    	if(l>=p){--mx[id],--tag[id];return;}
    	pushdown(id);
    	int mid=l+r>>1;
    	if(p<=mid) change(ls,l,mid,p);
    	change(rs,mid+1,r,p);
    	mx[id]=max(mx[ls],mx[rs]);
    }
    int main()
    {
    	n=read();
    	build(1,1,n);
    	for(int rig,lef,r,i=n;i;i--)
    	{
    		r=read()%i;
    		lef=s-ask(s);//左边个数
    		rig=i-lef;//右边个数
    		if(rig<=r) r-=rig;//左边
    		else r+=lef;
    		query(1,1,n,r+1);
    		change(1,1,n,s);
    	}
    	return 0;
    }
    

    2019.2.12

  • 相关阅读:
    整理公共基础库子系统和系统属性组件
    鸿蒙轻内核M核源码分析系列六 任务及任务调度(1)任务栈
    HarmonyOS三方件开发指南(19)-BGABadgeView徽章组件
    鸿蒙的DFX子系统
    安卓to鸿蒙系列:ButterKnife(一)
    基于Neptune开发板的键盘蓝牙模块DIY指南
    徒手撸一个Spring Boot中的starter
    这三道最基础的java面试题,你真的答得上来吗?
    奇葩java迭代器面试题,还真有很多人踩坑
    15道类和对象面试题,快看看自己会几道
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10366657.html
Copyright © 2020-2023  润新知