zoukankan      html  css  js  c++  java
  • 联考20200803 T2 感受清风









    分析:

    我的好像和题解不大一样
    先开一颗线段树维护贴着边缘的箱子,每一段区间维护一个\(mn\)表示能走过这段区间的最大列
    left和right实际上是一个镜像翻转,打个标记就好了
    对于加入和删除的箱子,暴力用一个二维数据结构维护,发现我们只关心列上区间的关系,就用空间比较小的主席树了
    当要进行left或者right操作的时候,把主席树上加的点加入线段树,把主席树清零就可以了
    查询的时候两个标记同时在线段树和主席树上查找,注意合并信息,类似线段树二分地找就好了

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    #define maxn 1000005
    
    using namespace std;
    
    inline int getint()
    {
    	int num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n,m;
    int a[maxn],mn[maxn<<2];
    int Rev,Mx;
    int rt[maxn],tot;
    int lc[maxn*21],rc[maxn*21],val[maxn*21];
    struct op{
    	int op,x,y;
    }Q[maxn];
    int cur;
    char s[maxn];
    
    inline void build(int i,int l,int r)
    {
    	if(l==r){mn[i]=a[l];return;}
    	int mid=(l+r)>>1;
    	build(i<<1,l,mid),build(i<<1|1,mid+1,r);
    	mn[i]=min(mn[i<<1],mn[i<<1|1]);
    }
    
    inline void update(int i,int l,int r,int p,int x)
    {
    	if(l==r){mn[i]+=x;return;}
    	int mid=(l+r)>>1;
    	if(p<=mid)update(i<<1,l,mid,p,x);
    	else update(i<<1|1,mid+1,r,p,x);
    	mn[i]=min(mn[i<<1],mn[i<<1|1]);
    }
    
    inline bool check(int now,int i)
    {return now?val[now]:(mn[i]>=Mx);}
    inline void insert(int &now,int i,int l,int r,int p,int x)
    {
    	if(!now)now=++tot;
    	if(l==r){val[now]=x;return;}
    	int mid=(l+r)>>1;
    	if(p<=mid)insert(lc[now],i<<1,l,mid,p,x);
    	else insert(rc[now],i<<1|1,mid+1,r,p,x);
    	val[now]=check(lc[now],i<<1)&check(rc[now],i<<1|1);
    }
    
    inline int getu(int now,int i,int l,int r,int p)
    {
    	if(r<=p&&check(now,i))return r-l+1;
    	if(l==r)return check(now,i);
    	int mid=(l+r)>>1;
    	if(p<=mid)return getu(lc[now],i<<1,l,mid,p);
    	int tmp=getu(rc[now],i<<1|1,mid+1,r,p);
    	if(tmp==p-mid)return getu(lc[now],i<<1,l,mid,mid)+tmp;
    	return tmp;
    }
    inline int getd(int now,int i,int l,int r,int p)
    {
    	if(p<=l&&check(now,i))return r-l+1;
    	if(l==r)return check(now,i);
    	int mid=(l+r)>>1;
    	if(p>mid)return getd(rc[now],i<<1|1,mid+1,r,p);
    	int tmp=getd(lc[now],i<<1,l,mid,p);
    	if(tmp==mid-p+1)return getd(rc[now],i<<1|1,mid+1,r,mid+1)+tmp;
    	return tmp;
    }
    
    int main()
    {
    	n=getint(),m=getint();
    	for(int i=1;i<=n;i++)a[i]=getint();
    	build(1,1,n);
    	int q=getint();
    	while(q--)
    	{
    		scanf("%s",s);
    		if(s[0]=='l'||s[0]=='r')
    		{
    			Rev=(s[0]=='r');
    			for(int i=1;i<=cur;i++)
    			{
    				update(1,1,n,Q[i].x,Q[i].op);
    				rt[Q[i].y]=0;
    			}
    			cur=0;continue;
    		}
    		int x=getint(),y=getint();
    		Mx=Rev?m-y+1:y;
    		if(s[0]=='a')
    		{
    			Q[++cur]=(op){1,x,y};
    			insert(rt[y],1,1,n,x,1);
    			continue;
    		}
    		if(s[0]=='d')
    		{
    			Q[++cur]=(op){-1,x,y};
    			insert(rt[y],1,1,n,x,0);
    			continue;
    		}
    		if(s[1]=='u')printf("%d\n",getu(rt[y],1,1,n,x));
    		if(s[1]=='d')printf("%d\n",getd(rt[y],1,1,n,x));
    	}
    }
    

  • 相关阅读:
    通过 INotifyPropertyChanged 实现观察者模式(转)
    Asp.net MVC中的ViewData与ViewBag(转)
    FireFox地址栏百度搜索
    ZigBee设备类型
    Array.prototype.slice.call(arguments) (转)
    泛型方法扩展
    定义IE的文档兼容模式
    C# Lazy<T>(转)
    AutoCAD2010/2012去掉搜索框
    python 集合类型
  • 原文地址:https://www.cnblogs.com/IzayoiDoyo/p/13429671.html
Copyright © 2011-2022 走看看