• [APIO 2010] [LOJ 3144] 奇怪装置 (数学)


    [APIO 2010] [LOJ 3144] 奇怪装置 (数学)

    题面

    分析

    考虑t1,t2时刻坐标相同的条件

    [egin{cases} t_1+lfloor frac{t_1}{B} floor equiv t_2+lfloor frac{t_2}{B} floor (mathrm{mod} A) \ t_1 equiv t_2 (mathrm{mod} B)\ end{cases} ]

    由第二个式子,可以令(t_1=t_2+Bk(k in N))
    代入式子1,(t_2+Bk+lfloor frac{t_2}{B}+k floor equiv t_2+lfloor frac{t_2}{B} floor(mathrm{mod} A))
    消元得((B+1)k equiv 0 (mathrm{mod} A))
    因此(k|frac{A}{gcd(A,B+1)}),
    代入上式,(t_1=t_2+Bfrac{A}{gcd(A,B+1)}(k in N))
    (t_1 equiv t _2 (mathrm{mod} frac{AB}{gcd(A,B+1)}))

    因此,可以把l,r取模(frac{AB}{gcd(A,B+1)}),然后问题就变成在([0,frac{AB}{gcd(A,B+1)}])上有若干条线段,求线段的并
    直接排序再(O(n))扫一遍即可
    注意(frac{AB}{gcd(A,B+1)})可能会超过long long范围,但注意到l,r都(leq 2 imes 10^{18}),如果(frac{AB}{gcd(A,B+1)})超过就强行设成$ 2 imes 10^{18}$

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm> 
    #define maxn 1000000
    #define maxr 2e18
    using namespace std;
    typedef long long ll;
    ll n,A,B;
    inline ll gcd(ll a,ll b){
    	return b==0?a:gcd(b,a%b);
    }
     
    struct seg{
    	ll l;
    	ll r;
    	seg(){
    		
    	}
    	seg(ll _l,ll _r){
    		l=_l;
    		r=_r;
    	}
    	friend bool operator < (seg p,seg q){
    		if(p.l==q.l) return p.r<q.r;
    		else return p.l<q.l; 
    	}
    }a[maxn+5],b[maxn*2+5];
    int cnt=0;
    int main(){
    	scanf("%I64d %I64d %I64d",&n,&A,&B);
    	for(int i=1;i<=n;i++){
    		scanf("%I64d %I64d",&a[i].l,&a[i].r);
    	}
    	ll C=A/gcd(A,B+1);
    	if(maxr/B<=C) C=maxr; //B*C<=2e18 
    	else C=C*B;
    	for(int i=1;i<=n;i++){
    		if(a[i].r-a[i].l>=C){
    			printf("%I64d
    ",C);
    			return 0;
    		}
    		if(a[i].l%C<=a[i].r%C){
    			b[++cnt]=seg(a[i].l%C,a[i].r%C);	
    		}else{
    			b[++cnt]=seg(0,a[i].r%C);
    			b[++cnt]=seg(a[i].l%C,C-1);
    		} 
    	}
    	sort(b+1,b+1+cnt);
    //	cnt=unique(b+1,b+1+cnt)-b-1;
    	ll l=b[1].l,r=b[1].r;
    	ll ans=0;
    	for(int i=2;i<=cnt;i++){
    		if(b[i].l>r+1){
    			ans+=(r-l+1);
    			l=b[i].l;
    			r=b[i].r;
    		}else if(b[i].r>r){
    			r=b[i].r;
    		}
    	} 
    	ans+=r-l+1;
    	printf("%I64d
    ",ans);
    } 
    
  • 相关阅读:
    php--------ThinkPHP3.2验证码使用
    mysql--------四种索引类型
    php--------递归函数
    php--------对象(object) 与 数组(array) 的转换
    ZH奶酪:Windows7+VirtualBox安装Ubuntu虚拟机问题总结
    第一次工作面试(蘑菇街)
    ZH奶酪:【阅读笔记】Deep Learning, NLP, and Representations
    web开发学习之旅
    隐马尔可夫模型实战
    ZH奶酪:Python中range和xrange的区别
  • 原文地址:https://www.cnblogs.com/birchtree/p/11395365.html
Copyright © 2020-2023  润新知