• 2019南昌网络赛H The Nth Item(打表找询问循环节 or 分段打表)


    https://nanti.jisuanke.com/t/41355

    思路

    • 从fib循环节入手,(O(1e7log(1e9))),tle
    • 因为只需要输出所有询问亦或后的结果,所以考虑答案的循环节,打表发现大于10w后的答案的循环节为2,(O(1e5log(1e18)))
    • 不考虑循环节,第一眼看过去这道题需要O(1)询问,其实仔细一想可以多一些常数,考虑分段打表,1e18分成三段打表,每一段的表长都是1e6,然后每次询问最多(O(2*矩阵相乘))
    #include<bits/stdc++.h>
    #define ll long long
    #define mk make_pair
    #define ft first
    #define se second
    #define pii pair<int,int>
    #define db double
    #define ls o<<1
    #define rs o<<1|1
    #define lowbit(x) (x&-x)
    using namespace std;
    const int M=2e6+5,T=1e6;
    const ll P=998244353;
    int x[2][2]={{1,0},{0,0}};
    int y[2][2]={{3,1},{2,0}};
    int z[2][2]={{1,0},{0,1}};
    ll q,n;
    struct mat{
        ll d[2][2];
        void init(int c[2][2]){
            for(int i=0;i<2;i++)for(int j=0;j<2;j++)d[i][j]=c[i][j];
        }
        mat operator *(const mat& rhp)const{
            mat tmp;
            for(int i=0;i<2;i++){
                for(int j=0;j<2;j++){
                    tmp.d[i][j]=0;
                    for(int k=0;k<2;k++)
                        tmp.d[i][j]=(tmp.d[i][j]+d[i][k]*rhp.d[k][j]%P)%P;
                }
            }
            return tmp;
        }
    }A[3][M];
    
    void init(){
        A[0][0].init(z);
        A[0][1].init(y);
        for(int i=2;i<=T;i++){
            A[0][i]=A[0][i-1]*A[0][1];
        }
        A[1][0].init(z);
        A[1][1]=A[0][T];
        for(int i=2;i<=T;i++){
            A[1][i]=A[1][i-1]*A[1][1];
        }
        A[2][0].init(z);
        A[2][1]=A[1][T];
        for(int i=2;i<=2*T;i++){
            A[2][i]=A[2][i-1]*A[2][1];
        }
    }
    ll gao(ll n){
        if(n==0)
            return 0;
        if(n==1)
            return 1;
        mat B;
        B.init(z);
        for(int i=0;i<3&&n;i++){
            int k=n%T;
            if(i==2)k=n;           //没有前导0
            B=B*A[i][k];
            n/=T;
        }
        return B.d[0][1];
    }
    int main(){
        cin>>q>>n;
        init();
        ll res=0,f;
        while(q--){
            f=gao(n);
            n^=f*f;
            res^=f;
        }
        cout<<res<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    POJ--2112--Optimal Milking【Floyd+Dinic+二分答案】
    HTML5之WEB Storage
    java多线程具体总结
    CSU 1541 There is No Alternative (最小生成树+枚举)
    Blade
    数据模型封装演示样例
    Java中接口和抽象类的比較
    句子逆序
    王立平--split字符串切割
    UVA 12538 Version Controlled IDE 解题报告
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/11510596.html
Copyright © 2020-2023  润新知