zoukankan      html  css  js  c++  java
  • BZOJ 4513 储能表

    数位DP?我哪会

    [0,n-1]可以拆成log段一定前缀之后任意的区间

    (log^2) 枚举区间对计数即可

    #include <cstdio>
    #include <algorithm>
    
    using std::min;
    using std::max;
    
    int T;
    
    long long N, M, K;
    long long n, m, kl, kr;
    
    int Cnt, Sum;
    
    int MOD;
    
    int sr;
    int sum(int a, int b){
    	sr=a+b;
    	if(sr>=MOD)	sr-=MOD;
    	return sr;
    }
    
    int mul(int a, int b){
    	return (int)((1LL*a*b)%(long long)(MOD));
    }
    
    int Norm(long long n){
    	return (int)(n%(long long)(MOD));
    }
    
    int Calc(long long n){
    	if(n&1LL)
    		return mul(Norm(n), Norm((n+1LL)>>1));
    	else	return mul(Norm(n>>1), Norm(n+1LL));
    }
    
    void Update(long long l, long long r, long long k){
    	Cnt=sum(Cnt, mul(Norm(r-l), Norm(k)));
    	Sum=sum(Sum, mul(sum(Calc(r), MOD-Calc(l)), Norm(k)));
    }
    
    int main(){
    	
    	scanf("%d", &T);
    	
    	while(T--){
    		
    		scanf("%lld%lld%lld%d", &N, &M, &K, &MOD);
    		
    		Sum=0;Cnt=0;
    		
    		for(int i=0;i<60;++i){
    			if((N>>i)&1){
    				n=(N>>(i+1))<<(i+1);
    				for(int j=0, l;j<60;++j){
    					if((M>>j)&1){
    						m=(M>>(j+1))<<(j+1);
    						l=max(i, j);
    						kl=n^m;kl=(kl>>l)<<l;
    						kr=kl+(1LL<<l)-1LL;
    						if(K<kr)	Update(max(kl-1, K), kr, (1LL<<min(i, j)));
    					}
    				}
    			}
    		}
    		
    		Sum=sum(Sum, MOD-mul(Cnt, Norm(K)));
    		
    		printf("%d
    ", Sum);
    		
    	}
    	
    	
    	
    	
    	return 0;
    }
    
    /*
    3
    2 2 0 100
    3 3 0 100
    3 3 1 100
    
    2
    12
    6
    
    */
    
    
  • 相关阅读:
    Remote Procedure Call (RPC) Locator与X3
    Delphi的悬浮窗口
    改变CSS样式
    JavaScript 打印Web页面指定区域的信息
    判断页面元素存在与否
    如何处理HTML标签属性
    jQuery 获取和设置表单元素
    如何添加/移除CSS类
    处理网页内容
    正则表达式 收集
  • 原文地址:https://www.cnblogs.com/Pickupwin/p/BZOJ4513.html
Copyright © 2011-2022 走看看