zoukankan      html  css  js  c++  java
  • uoj#218. 【UNR #1】火车管理

    题目描述


    n,m<=5e5,x<=1e3

    题解

    想了一下就想出了log^2的,之后刚了一个下午尝试去掉一个log结果发现把set改成优先队列就过了

    log^2的自然做法:

    在线段树上set里挂加进去的数,如果下传的话时间会假,因此不下传标记

    弹栈就单点查询,把经过的所有区间内时间最大的弹掉,第二大的就是新的值

    弹掉之后下传,注意只需要下传一个标记,往下一共有log个区间

    时间是log^2的,用优先队列即可通过并且不是最慢

    题解一个log的自然做法:

    主席树直接维护每个时刻的栈顶(时间/值),弹栈等于把某个位置修改为某个时间该位置的值,直接查询即可

    简单自然

    code

    log^2

    #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 n,m,tp,Tp,i,j,k,l,x,y,z,ans,T,Find;
    char st[21],ch;
    struct type{int x,t;} Find2;
    bool operator < (type a,type b) {return a.t<b.t;}
    struct tree1{
    	int tr[2000001],Tr[2000001];
    	void down(int t,int len)
    	{
    		if (Tr[t]>-1)
    		{
    			if (len>1) Tr[t*2]=Tr[t*2+1]=Tr[t];
    			tr[t]=Tr[t]*len;Tr[t]=-1;
    		}
    	}
    	void change(int t,int l,int r,int x,int y,int s)
    	{
    		int mid=(l+r)/2;
    		down(t,r-l+1);
    		if (x<=l && r<=y)
    		{
    			Tr[t]=s,down(t,r-l+1);
    			return;
    		}
    		down(t*2,mid-l+1),down(t*2+1,r-mid);
    		
    		if (x<=mid) change(t*2,l,mid,x,y,s);
    		if (mid<y) change(t*2+1,mid+1,r,x,y,s);
    		tr[t]=tr[t*2]+tr[t*2+1];
    	}
    	int find(int t,int l,int r,int x,int y)
    	{
    		int mid=(l+r)/2,ans=0;
    		down(t,r-l+1);
    		if (x<=l && r<=y) return tr[t];
    		
    		if (x<=mid) ans+=find(t*2,l,mid,x,y);
    		if (mid<y) ans+=find(t*2+1,mid+1,r,x,y);
    		return ans;
    	}
    } t1;
    struct tree2{
    	priority_queue<type> tr[2000001];
    	void change(int t,int l,int r,int x,int y,type s)
    	{
    		int mid=(l+r)/2;
    		if (x<=l && r<=y) {tr[t].push(s);return;}
    		
    		if (x<=mid) change(t*2,l,mid,x,y,s);
    		if (mid<y) change(t*2+1,mid+1,r,x,y,s);
    	}
    	void find(int t,int l,int r,int x)
    	{
    		int mid=(l+r)/2;
    		type s;
    		
    		if (!tr[t].empty())
    		{
    			s=tr[t].top();
    			if (s.t>Find2.t) Find=t,Find2=s;
    		}
    		if (l==r) return;
    		
    		if (x<=mid) find(t*2,l,mid,x);
    		else find(t*2+1,mid+1,r,x);
    	}
    	void Change(int t,int l,int r,int x,type s)
    	{
    		int mid=(l+r)/2;
    		if (l==r) return;
    		
    		if (x<=mid)
    		{
    			if (t>=Find) tr[t*2+1].push(s);
    			Change(t*2,l,mid,x,s);
    		}
    		else
    		{
    			if (t>=Find) tr[t*2].push(s);
    			Change(t*2+1,mid+1,r,x,s);
    		}
    	}
    } t2;
    
    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 Write(int x) {int i=0; if (!x) {putchar('0');putchar('
    ');return;} while (x) st[++i]=x%10+'0',x/=10; while (i) putchar(st[i--]);putchar('
    ');}
    
    int main()
    {
    	#ifdef file
    	freopen("uoj218.in","r",stdin);
    	freopen("uoj218.out","w",stdout);
    	#endif
    	
    	memset(t1.Tr,255,sizeof(t1.Tr));
    	
    	Read(n),Read(m),Read(tp);
    	fo(T,1,m)
    	{
    		Read(Tp);
    		switch (Tp)
    		{
    			case 1:{
    				Read(j);Read(k);j=(j+ans*tp)%n+1;k=(k+ans*tp)%n+1;
    				x=min(j,k),y=max(j,k);
    				ans=t1.find(1,1,n,x,y);
    				Write(ans);
    				break;
    			}
    			case 2:{
    				Read(x);x=(x+ans*tp)%n+1;Find=0;Find2.t=-1;
    				t2.find(1,1,n,x);
    				if (Find)
    				{
    					t2.tr[Find].pop();
    					t2.Change(1,1,n,x,Find2);
    					
    					Find=0;Find2={0,-1};
    					t2.find(1,1,n,x);
    					t1.change(1,1,n,x,x,Find2.x);
    				}                      
    				break;
    			}
    			case 3:{
    				Read(j),Read(k),Read(z);j=(j+ans*tp)%n+1;k=(k+ans*tp)%n+1;
    				x=min(j,k),y=max(j,k);
    				t1.change(1,1,n,x,y,z);
    				t2.change(1,1,n,x,y,{z,T});
    				break;
    			}
    		}
    	}
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    mysql 判断时间 语法
    SVN权限配置
    redis 安装 配置 及启动
    SVN搭建(linux 7)
    Maven 逆向工程
    git 设置只输入一次用户名和密码
    java环境变量配置(win7)
    Navicat Premium 12 激活
    linux 常用命令
    MVC的验证(模型注解和非侵入式脚本的结合使用)
  • 原文地址:https://www.cnblogs.com/gmh77/p/13401015.html
Copyright © 2011-2022 走看看