zoukankan      html  css  js  c++  java
  • Codeforces Round #553 (Div. 2) C 等差数列求和 + 前缀和

    https://codeforces.com/contest/1151/problem/C

    题意

    有两个等差数列(1,3,5,..),(2,4,6,...),两个数列轮流取1,2,4,...,(2^n)组成一个新的数列,然后询问区间l,r的和

    题解

    • 一开始总想着怎么计算中间那一段,其实用前缀和很好处理
    • 数太大,第二个数也要取模才能相乘

    代码

    #include<bits/stdc++.h>
    #define ll long long 
    using namespace std;
    const ll cha=2;
    const ll P = 1e9+7;
    ll pw(ll bs,ll x){
    	ll ans=1;
    	while(x){
    		if(x&1)ans*=bs;
    		bs*=bs;
    		x>>=1;
    	}
    	return ans;
    }
    
    ll pw(ll bs,ll x,ll MOD){
    	ll ans=1;
    	while(x){
    		if(x&1)ans=ans*bs%MOD;
    		bs=bs*bs%MOD;
    		x>>=1;
    	}
    	return ans;
    }
    const ll pw2=pw(2,P-2,P);
    
    ll cal(ll x){
    	ll i=1;int odd=1;
    	ll od=1,ed=2,d,lt;
    	ll ans=0;
    	while(x>=pw(2,i-1)){
    		//cout<<i<<" "<<ans<<endl;
    		//cout<<od<<" "<<ed<<endl;
    		x-=pw(2,i-1);
    		d=pw(2,i-1);
    		if(odd){
    			ans+=(od%P*(d%P)%P+d%P*((d-1)%P)%P)%P;
    			ans%=P;
    			od+=d*cha;
    		}else{
    			ans+=(ed%P*(d%P)%P+d%P*((d-1)%P)%P)%P;
    			ans%=P;
    			ed+=d*cha;
    		}
    		odd^=1;
    		i++;
    	}
    	//cout<<i<<endl;
    	//cout<<ans<<endl;
    	if(x==0)return ans;
    	d=x;
        if(odd){
    			ans+=(od%P*(d%P)%P+d%P*((d-1)%P)%P)%P;
    			ans%=P;
    			od+=d*cha;
    		}else{
    			ans+=(ed%P*(d%P)%P+d%P*((d-1)%P)%P)%P;
    			ans%=P;
    			ed+=d*cha;
    		}    
    	return ans;	
    }
    		
    
    int main(){
    	ll l,r;
    	cin>>l>>r;
    	cout<<(cal(r)-cal(l-1)+P)%P;
    }
    
  • 相关阅读:
    Kattis
    Kattis
    Kattis
    Kattis -Backspace
    Kattis
    Kattis
    Kattis
    Hihocoder1061-Beautiful String
    Hihocoder1350-Binary Watch
    Hihocoder1458-Parentheses Matching(stack,vector)
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/10812155.html
Copyright © 2011-2022 走看看