zoukankan      html  css  js  c++  java
  • 6507. 【GDOI2020模拟03.11】感受清风(wind)

    题目描述

    题解

    比赛时的想法:离线,把相关的区间找出来,再向下拓展一个儿子以便向上合并,然后维护区间是否全满

    吹风等于把y翻转

    主席树,每次吹风时只维护源线段树,单点修改时复制整棵树,每棵树维护区间最小方便二分,修改就是改成0或y

    比较好写

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    #define ll long long
    #define file
    using namespace std;
    
    int tr[25000001][3],c[1000001],t[1000001],rt[1000001],d[1000001][2],n,m,Q,i,j,k,l,len,T,Find,tot,x,y;
    bool Bz,Find2;
    char st[7],ch;
    
    void Read(int &x)
    {
    	x=0;
    	
    	ch=getchar();
    	while (ch<'0' || ch>'9') ch=getchar();
    	while (ch>='0' && ch<='9') x=x*10+(ch-'0'),ch=getchar();
    }
    
    void copy(int t)
    {
    	++len;
    	tr[len][0]=tr[t][0];
    	tr[len][1]=tr[t][1];
    	tr[len][2]=tr[t][2];
    }
    
    void New(int t,int x)
    {
    	copy(tr[t][x]);
    	tr[t][x]=len;
    }
    
    void mt(int t,int l,int r)
    {
    	int mid=(l+r)/2;
    	
    	len=max(len,t);
    	if (l==r) {tr[t][2]=c[l];return;}
    	
    	tr[t][0]=t*2;
    	tr[t][1]=t*2+1;
    	
    	mt(tr[t][0],l,mid);
    	mt(tr[t][1],mid+1,r);
    	
    	tr[t][2]=min(tr[tr[t][0]][2],tr[tr[t][1]][2]);
    }
    
    void change(int t,int l,int r,int x,int s)
    {
    	int mid=(l+r)/2;
    	
    	if (l==r) {tr[t][2]=s;return;}
    	
    	if (x<=mid)
    	New(t,0),change(tr[t][0],l,mid,x,s);
    	else
    	New(t,1),change(tr[t][1],mid+1,r,x,s);
    	
    	tr[t][2]=min(tr[tr[t][0]][2],tr[tr[t][1]][2]);
    }
    void findu(int T,int t,int l,int r,int x)
    {
    	int mid=(l+r)/2;
    	
    	if (l==r) {if (tr[t][2]>=T) Find=l; else Find2=1;return;}
    	
    	if (x<r)
    	{
    		if (mid<x)
    		findu(T,tr[t][1],mid+1,r,x);
    		if (!Find2)
    		findu(T,tr[t][0],l,mid,x);
    	}
    	else
    	{
    		if (tr[t][2]>=T)
    		Find=l;
    		else
    		{
    			if (tr[tr[t][1]][2]>=T)
    			Find=mid+1,findu(T,tr[t][0],l,mid,x);
    			else
    			findu(T,tr[t][1],mid+1,r,x);
    		}
    	}
    }
    void findd(int T,int t,int l,int r,int x)
    {
    	int mid=(l+r)/2;
    	
    	if (l==r) {if (tr[t][2]>=T) Find=l; else Find2=1;return;}
    	
    	if (l<x)
    	{
    		if (x<=mid)
    		findd(T,tr[t][0],l,mid,x);
    		if (!Find2)
    		findd(T,tr[t][1],mid+1,r,x);
    	}
    	else
    	{
    		if (tr[t][2]>=T)
    		Find=r;
    		else
    		{
    			if (tr[tr[t][0]][2]>=T)
    			Find=mid,findd(T,tr[t][1],mid+1,r,x);
    			else
    			findd(T,tr[t][0],l,mid,x);
    		}
    	}
    }
    
    void Change(int t,int l,int r,int x,int s)
    {
    	int mid=(l+r)/2;
    	
    	if (l==r) {tr[t][2]+=s;return;}
    	
    	if (x<=mid)
    	Change(tr[t][0],l,mid,x,s);
    	else
    	Change(tr[t][1],mid+1,r,x,s);
    	
    	tr[t][2]=min(tr[tr[t][0]][2],tr[tr[t][1]][2]);
    }
    
    void pd(int x)
    {
    	if (t[x]<T)
    	{
    		t[x]=T;
    		
    		copy(1);
    		rt[x]=len;
    	}
    }
    
    void clear()
    {
    	while (tot)
    	{
    		Change(1,1,n,d[tot][0],d[tot][1]);
    		--tot;
    	}
    }
    
    int main()
    {
    	freopen("wind.in","r",stdin);
    	#ifdef file
    	freopen("wind.out","w",stdout);
    	#endif
    	
    	Read(n);Read(m);
    	fo(i,1,n)
    	Read(c[i]);
    	
    	mt(1,1,n);
    	
    	Read(Q);T=1;
    	for (;Q;--Q)
    	{
    		scanf("%s",st);
    		
    		if (st[0]!='l' && st[0]!='r')
    		{
    			Read(x),Read(y);
    			if (Bz) y=m-y+1;
    			
    			pd(y);
    		}
    		
    		switch (st[0])
    		{
    			case 'a':{++tot;d[tot][0]=x;d[tot][1]=1; change(rt[y],1,n,x,y);break;}
    			case 'd':{++tot;d[tot][0]=x;d[tot][1]=-1;change(rt[y],1,n,x,0);break;}
    			case 'q':{
    				switch (st[1])
    				{
    					case 'u':{Find=x+1;Find2=0;findu(y,rt[y],1,n,x);printf("%d
    ",x-Find+1);break;}
    					case 'd':{Find=x-1;Find2=0;findd(y,rt[y],1,n,x);printf("%d
    ",Find-x+1);break;}
    				}
    				break;
    			}
    			case 'l':{clear();Bz=0;++T;break;}
    			case 'r':{clear();Bz=1;++T;break;}
    		}
    	}
    	
    	fclose(stdin);
    	fclose(stdout);
    	
    	return 0;
    }
    
  • 相关阅读:
    [LeetCode]题解(python):119-Pascal's Triangle II
    [LeetCode]题解(python):118-Pascal's Triangle
    [LeetCode]题解(python):117-Populating Next Right Pointers in Each Node II
    寒假自学进度8
    寒假自学进度7
    寒假自学进度6
    寒假自学5
    寒假自学学习4
    寒假自学进度3
    寒假自学进度2
  • 原文地址:https://www.cnblogs.com/gmh77/p/12494931.html
Copyright © 2011-2022 走看看