2018年7月23日暑假训练日记

  早上看了前三道题目。

  第一个是纯暴力,一眼看出来了,Question for the Leader是一个结论题,对于一棵树,如果可以把这棵树分成大小都为k的n/k份,那子树大小是k的倍数的节点恰好有n/k个。(任意选定一个根),这个结论叙述的并不是很好,所以就花了一段时间,第三个则是一个状压dp,由于不会状压dp,就去专门看了一下,但是还没入门就开始了下午的比赛。

  下午总共出了四道题目,两道水题,一道优先队列的贪心,一个模拟。然后就一直在搞那个规律题,规律与最后直播讲的大致相同,但是二分被卡了常数,但是因为讲题人没用这种方法写,所以并不知道这样是不是真的对,但赛后改了常数仍然tle,可能是我的二分出现了跳不出来的状况,这也是我的二分恐惧症,但是已经很接近真相了,纪念一下,明天争取肝出来这个题目:

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#define mo 1000000007
using namespace std;
long long a[1010],sum[1010];
long long getnum(long long n){
    long long num=0;
    long long nn=n;
    while (nn){
        num+=nn/2;
        nn=nn/2;
    }
    return num+n+1;
}
long long qpow(long long a,long long b){
    long long ans=1;
    long long k=a;
    while(b){
        if(b&1)ans=ans*k%mo;
        k=k*k%mo;
        b>>=1;
    }
    return (ans+mo)%mo;
}
long long getb(long long x){
    return (x%mo+(((x%mo)*((x-1)%mo))*qpow(2,mo-2)%mo)+mo)%mo;
}
long long getans(long long n){
    long long ans=0;
    long long temp=1;
    long long fun=2;
    while (n){
        ans=(ans+(temp%mo)*(getb(n)%mo))%mo;
        n/=fun;
        temp*=2;
    }
    return (ans+1+mo)%mo;
}
long long solve(long long n){
    long long l=1,r=n;
    long long fun;
    while (l<=r){
        long long mid=(l+r)/2;
        if (getnum(mid)<=n){
            if (getnum(mid+1))>n){
                fun=mid;
                break;
            }
            else {
                l=mid;
            }
        }
        else {
            r=mid;
        }
    }
    long long ans;
    long long fuck=getnum(mid);
    ans=(getans(mid)+(((n-fuck)%mo)*((mid+1)%mo))%mo+mo)%mo;
    return ans;
}
int main(){

    long long i,j,t;
    long long n;
    a[1]=1;
    a[2]=1;
    sum[1]=1;
    sum[2]=2;
    for(i=3;i<=1000;i++){
        long long k1=i-a[i-1];
        long long k2=i-1-a[i-2];
        a[i]=(a[k1]+a[k2])%mo;
        sum[i]=(sum[i-1]+a[i])%mo;
    }
    scanf("%lld",&t);
    while (t--){
        scanf("%lld",&n);
        if (n<=1000){
            printf("%lld\n",sum[n]);
        }
        else {
            printf("%lld\n",solve(n));
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/m0_37772713/article/details/81174135