• 2017国家集训队作业[arc082d]Sandglass


    2017国家集训队作业[arc082d]Sandglass

    题意:

    ​ 有一个沙漏,初始时(A)瓶在上方,两个瓶子的最大容量都为(X)克,沙子流动的速度为(1g)每单位时间。给出(K)个时间点(r_1sim r_K)表示在这几个时间点,漏斗会上下翻转,无视翻转时间。给出(Q)个询问,每个询问两个数(t_i,a_i),表示若初始时(A)瓶有(a_i)克沙子,询问第(t_i)单位时间时,(A)瓶中会有多少克沙子?((X,t_i,r_ileq 10^9,a_ileq X,Kleq 10^5),输入保证序列({r_i})({t_i})为升序)

    题解:

    ​ 最后半小时想出来,真的惨。

    ​ 观察发现(A)瓶中的沙子函数图像由若干个斜率为(1,-1,0)的一次函数组成。若存在某一时刻,该函数的斜率为(0)(即碰到上下边界),那么在此以后,函数的图像与截距((a_i))无关。

    ​ 初始截距((a_i))的取值会使该函数出现三种情况:

    (1.)只会碰到上边界

    (2.)只会碰到下边界

    (3.)上下边界都不会碰到

    ​ 还存在一种情况:无论(a_i)的值是什么,该函数总会碰到上或下边界。

    ​ 分别维护(a)的区间即可。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define fo(i,l,r) for(int i=l;i<=r;i++)
    #define of(i,l,r) for(int i=l;i>=r;i--)
    #define fe(i,u) for(int i=head[u];i;i=e[i].next)
    using namespace std;
    typedef long long ll;
    inline int rd()
    {
        static int x,f;
        x=0,f=1;
        char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    const int N=100010;
    int X,K,Q,T[N],ty;
    
    struct cha{
    	int a1,x1,a2,x2,x;
    	bool flag;
    	inline int get(int a)
    	{
    		if(flag)return x;
    		if(a<=a1)return x1;
    		if(a>=a2)return x2;
    		return a-a1+x1;
    	}
    }c[N];
    
    inline void gao(int i,int tim)
    {
    	if(c[i].flag){
    		c[i].x+=ty*tim;
    		c[i].x=max(0,c[i].x);
    		c[i].x=min(c[i].x,X);
    		return;
    	}
    	if(ty==-1){
    		if(c[i].x2<=tim){
                c[i].flag=1;c[i].x=0;
                return;
            }
            if(tim>=c[i].x1){c[i].a1+=tim-c[i].x1;c[i].x1=0;c[i].x2-=tim;}
            else{c[i].x1-=tim;c[i].x2-=tim;}
    	}
    	else{
    		if(c[i].x1+tim>=X){
    			c[i].flag=1;c[i].x=X;
    			return;
    		}
    		if(c[i].x2+tim>=X){c[i].a2-=c[i].x2+tim-X;c[i].x2=X;c[i].x1+=tim;}
    		else{c[i].x1+=tim;c[i].x2+=tim;}
    	}
    }
    
    int main()
    {
    	freopen("inc.txt","r",stdin);
    	X=rd();K=rd();
    	c[0].a1=c[0].x1=0;c[0].a2=c[0].x2=X,c[0].x=0;
    	c[0].flag=0;ty=-1;
    	fo(i,1,K)T[i]=rd(),c[i]=c[i-1],gao(i,T[i]-T[i-1]),ty=-ty;
    	int j=0;
    	Q=rd();ty=-1;
    	fo(i,1,Q){
    		int t=rd(),a=rd();
    		while((j<K&&T[j+1]<=t))j++,ty=-ty;
    		int ans=c[j].get(a);
    		ans+=ty*(t-T[j]);
    		ans=min(ans,X);
    		ans=max(ans,0);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
    

    UPD:2018/8/19 补上了代码

  • 相关阅读:
    Javascript设计模式理论与实战:单例模式
    详解CSS盒模型
    linux添加计划任务
    python删除目录下七天前创建的文件
    centos上源码安装clang 3.8
    使用postman发送数据并构建collections执行测试
    python多线程实现同时执行两个while循环
    使用Python写Windows Service服务程序
    用Pyinstaller打包发布exe应用
    使用Jmeter监测服务器cpu、内存等性能
  • 原文地址:https://www.cnblogs.com/JackyhhJuRuo/p/9498575.html
Copyright © 2020-2023  润新知