快速跳转

至至子的等差中项

int main() {
    int a,b;cin>>a>>b;
    cout<<2*b-a<<"\n";
    return 0;
}

至至子的按位与

thinking

尽可能的大,保证a&c=b&ca\&c=b\&c,就是在cc的每一位上尽可能地取1,所以aabb相同位上都取1即可,注意一下范围

vii c(3,vi(64,0));
void getnum(ll x,int i) {
    int cnt=0;
    while(x) {
        if((x&1)==1)
            c[i][cnt]=1;
        x>>=1;
        ++cnt;
    }
}
void solve() {
    ll a,b;cin>>a>>b;
    getnum(a,0);
    getnum(b,1);
    for(int i=0;i<64;++i) {
        if(c[0][i]==c[1][i])
            c[2][i]=1;
    }
    ll ans=0;
    for(int i=0;i<63;++i) {
        ans+=(ll)c[2][i]<<i;
    }
    cout<<ans<<"\n";
}

至至子的斐波那契

数列递增非常的快,范围在1e181e18T100T\le100直接把数列求出来暴力即可,注意那个level的坑

vector<ll> a={1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 7778742049, 12586269025, 20365011074, 32951280099, 53316291173, 86267571272, 139583862445, 225851433717, 365435296162, 591286729879, 956722026041, 1548008755920, 2504730781961, 4052739537881, 6557470319842, 10610209857723, 17167680177565, 27777890035288, 44945570212853, 72723460248141, 117669030460994, 190392490709135, 308061521170129, 498454011879264, 806515533049393, 1304969544928657, 2111485077978050, 3416454622906707, 5527939700884757, 8944394323791464, 14472334024676221, 23416728348467685, 37889062373143906, 61305790721611591, 99194853094755497, 160500643816367088, 259695496911122585, 420196140727489673, 679891637638612258};
void solve() {
    ll n;cin>>n;
    ll level=889989708002357095;
    if(n>=level) {
        cout<<a.size()+1<<"\n";
        return;
    }
    int len=sz(a);
    ll cha=abs(a[0]-n);
    int ans=0;
    for(int i=0;i<len;++i) {
        if(cha>abs(a[i]-n)) {
            cha=abs(a[i]-n);
            ans=i;
        }
    }
    cout<<ans+1<<'\n';
}

至至子的鸿门宴

thinking

贪心吧,我们发现,当我们操作aia_i的时候(直到不能再被操作),如果我们后面再次动aia_i的前面的数,aia_i就可能还能操作,因此,我们从左到右依次操作。结果就很显然了。

void solve() {
    int n;cin>>n;
    vi a(n),c(n);
    for(auto &x:a) cin>>x;
    string ans[2]={"SSZ","ZZZ"};
    int cnt=a[0]-1;
    a[0]=1;
    for(int i=1;i<n;++i) {
        cnt+=a[i]-a[i-1]-1;
        a[i]=a[i-1]+1;
        cnt%=2;
    }
    cnt%=2;
    cout<<ans[cnt]<<"\n";
}

至至子的长链剖分

thinking

思路很明显,就是构造树,将树分成1层1层的,从下往上0到1…,即是,我们每次选两层,判断能不能构造。一般,当数值大的那一层的节点数小于等于数值小的那一层节点数即可。进行加边的时候,注意判断一下即可。需要注意的是,当最高层出现多个节点的时候,显然是错的,但是上述方法判断不出来,需要加特判。

int temp;
void solve() {
    int n;cin>>n;
    map<int,vi> hs;
    vi e[n+1];
    vii ans;
    for(int i=0;i<n;++i) {
        cin>>temp;
        hs[temp].pb(i+1);
    }
    auto it=hs.end();--it;
    if(sz(it->second)>1) {
        cout<< -1 <<"\n";
        return;
    }
    for(auto pre=hs.begin(),mid=++hs.begin();mid!=hs.end();++pre,++mid) {
        vi midnum=mid->second;
        vi prenum=pre->second;
        int len0=sz(prenum);
        int len1=sz(midnum);
        int pos=0;
        for(int i=0;i<len0;++i) {
            e[midnum[pos%len1]].pb(prenum[i]);
            ans.pb({midnum[pos%len1],prenum[i]});
            ++pos;
        }
        if(pos<len1) {
            cout<< -1<< "\n";
            return;
        }
    }
    cout<<(--hs.end())->second[0]<<"\n";
    for(auto x:ans) cout<<x[0]<<" "<<x[1]<<"\n";
}