76真坏,让我的F红红的

红红的

A.题解的token计算

按题意输出即可

void solve(){
    ll n;cin>>n;
    cout<<fixed<<setprecision(12)<<150*1.0*log(n)<<'\n';
}

B.76修地铁

按题意模拟即可。

void solve(){
    ll c1 = 0, c2 = 0, c3 = 0, c4 = 0;
    ll n;cin>>n;
    for(ll i=1;i<=n;i++){
        if (i % 5 == 0)c1 += 2;
        if (i % 10 == 5)c2 += 1;
        if (i % 20 == 0)c3 += 3;
        else c4 += 2;
    }
    cout<<c1<<' '<<c2<<' '<<c3<<' '<<c4<<'\n';
}

C.76选数

要最大化异或和,可以想到把每一位全部变成

对于 , 存在一个比 小的数字使得异或和全部是

例如对于 ,取 ,可以使得 的每一位二进制都变成

又因为无法把 的更高位变成 ,因此答案就是把 的每一位变成

void solve(){
    ll n;cin>>n;
    cout<<((1ll<<(__lg(n)+1))-1)<<'\n';
}

D.76构造

注意到一定有一段区间元素的 。(包含 的那一段)

所以如果 为偶数,一定不可能。

为奇数时,我们可以让 中除 外每个二进制位为单独的一段区间。剩下的数字中一定有 一定为

例如 时 我们把 作为单独的区间,剩下的数字 作为另一个区间。

如果 中有一位二进制的大小超过 ,则这位二进制无法被构造出来,此时不可能。

注意边界特判。

void solve(){
    ll n = read(), m = read();
    if(n == 1){
        if(m==1){
            puts("1\n1\n1 1");
        }
        else{
            puts("-1");
        }
        return;
    }
    if(n==2&&m==1){
        puts("1 2\n1\n1 2");
        return;
    }
    if(m%2==0){
        puts("-1");
        return;
    }
    vector<ll> p, f(n+1);
    ll cnt = 0;
    for(ll bit=63;bit>=1;bit--){
        if((m>>bit)&1){
            if((1ll<<bit)>n){
                puts("-1");
                return;
            }
            cnt++;
            p.pb(1ll<<bit);
            f[1ll<<bit] = 1;
        }
    }
    for(ll i=1;i<=n;i++){
        if(!f[i]) p.pb(i);
    }
    for(ll i=0;i<n;i++){
        pt(p[i]),putchar(i==n-1?'\n':' ');
    }
    vector<PLL> ops;
    for(ll i=1;i<=cnt;i++){
        ops.pb({i, i});
    }
    if (cnt < n)
        ops.pb({cnt+1, n});
    pt(ops.size()),puts("");
    for(auto [l, r]:ops){
        pt(l),putchar(' '),pt(r), puts("");
    }
}

E.qcjj寄快递

高中数学题

以下过程中为区分距离和自然常数,设距离为

,则

时, 。且

因为 ,所以 时,即 时,取

带入原式得:

时,

时,

图:

mln2<1

图:

mln2 \ge 1

void solve() {
    ll n;cin>>n;
    vector<pair<db, db>> p(n+1);
    for(ll i=1;i<=n;i++) cin>>p[i].fi>>p[i].se;
    db ans = 0;
    for(ll i=1;i<n;i++){
        auto [x1, y1] = p[i];
        auto [x2, y2] = p[i+1];
        db m = sqrtl(pow(x1-x2, 2)+pow(y1-y2, 2));
        db x = log2(m * log(2));
        if (m * log(2) > 1){
            ans += 2 * x + 2 * m/pow(2, x);
        }
        else{
            ans += 2 * m;
        }
    }
    cout<<fixed<<setprecision(12)<<ans<<'\n';
}

F. 幂中幂plus

由于 ,因此 最多有 个取值,必定存在循环节。

由于循环节不可能超过 ,可以暴力求出循环节。

具体为,不断循环直到出现重复数字,此时就找到了循环节。

找到循环节后就可以 回答每个询问。

注意 可能很大,快速幂不要爆 以及 指数为 要返回

void solve(){
    ll b = read(), c0 = read();
    MOD = read();
    if(MOD == 1){
        ll q = read();
        while(q--){
            print(0);
        }
        return;
    }
    vector<ll> memo(MOD+1, -1);
    ll c = ksm(b, c0), cnt=0;
    vector<ll> pre(1, 0);
    while(memo[c]==-1){
        cnt++;
        memo[c] = cnt;
        pre.pb((pre.back()+c)%MOD);
        c = ksm(b, c);
    }
    ll len = cnt - memo[c] + 1;
    ll su = (pre[cnt]-pre[memo[c]-1]+MOD)%MOD;
    ll q = read();
    while(q--){
        ll k = read();
        if (k <= cnt){
            print(pre[k]%MOD);
        }
        else{
            ll t = (k -memo[c] + 1)/len%MOD;
            ll ans = t * su % MOD;
            ans = (ans + pre[memo[c]-1])%MOD;
            ll r = (k - memo[c] + 1)%len;
            ans = (ans + pre[memo[c]-1+r]-pre[memo[c]-1]+MOD)%MOD;
            print(ans);
        }
    }
}