zoukankan      html  css  js  c++  java
  • [2020多校联考]简单题

    2020.11.23

    解法

    题目只要求求出 (C) 的值,它就提示我们 (C)(A)(B) 的值没有太大关系。照着这个思路我们把 (A) (B) 合并一下,搞成二元组。对 (A+Bleq C)((A+B,C) o(2(A+B),C-(A+B))),对 (A+B>C)((A+B,C) o((A+B)-C,2C))。我们发现 (AB) 始终可以并在一起,干脆直接记为 (D)。对 (Dleq C)((D,C) o(2D,C-D)),对 (D>C)((D,C) o(D-C,2C))。这两个式子有很大的共性,可以说成是对称的。

    while(k--){
        if(a<=c) c-=a,a<<=1;
        else a-=c,c<<=1;
    } 
    

    (然而这波并没有任何的加成效果)

    再观察,发现 (2C) 可以写成 (C+C),又左边是 (D-C),那么二元组内的和是没有变的,始终为 (A+B+C)。(这大概又提示我们和模运算有关?)

    这个暴力不能优化的原因在于其中一条语句执行了一定次数,就会跳过去执行另一条语句。实际上是交换 (A)(C) 的值(因为式子是对称的)。大胆尝试,如果到了临界点不交换会发生什么,令 (S=C+D) ,那么 (C+C=C+(S-D)=(C-D)+S)(D-C=D-(S-D)=2D-S)。我们发现这交不交换的本质其实是一样的,只不过区别于有没有加上一个 (S)(A+B+C),所以可以一直乘 (2),然后对 (S) 取模即可。

    #include<stdio.h>
    #define ll long long
    #define N 100007
     
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
     
    ll a,c,Mod;
    int T,k;
     
    ll qpow(ll x,ll y){
        ll ret=1,cnt=0;
        while(y>=(1LL<<cnt)){
            if(y&(1LL<<cnt)) ret=(ret*x)%Mod;
            x=(x*x)%Mod,cnt++;
        }
        return ret;
    } 
     
    int main(){
    //  freopen("easy.in","r",stdin);
    //  freopen("easy.out","w",stdout);
        T=read();
        while(T--){
            a=read()+read(),c=read(),k=read();
            Mod=a+c;
            printf("%lld
    ",c*qpow(2LL,k)%Mod);
        }
    }
    
  • 相关阅读:
    结构体作为函数参数
    自定义子窗口与主窗口通信
    Qt性能问题
    后缀表达式、中缀表达式
    QMap的使用
    自定义QSS
    Qt查找孩子findChild
    ThinkPHP 3.2.3 数据缓存与静态缓存
    Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别  Pig
    Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别  Pig
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/14024562.html
Copyright © 2011-2022 走看看