QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#620731#4646. PhotosicealsoheatAC ✓303ms8328kbC++207.1kb2024-10-07 20:49:582024-10-07 20:49:58

Judging History

你现在查看的是最新测评结果

  • [2024-10-07 20:49:58]
  • 评测
  • 测评结果:AC
  • 用时:303ms
  • 内存:8328kb
  • [2024-10-07 20:49:58]
  • 提交

answer

#pragma GCC optimize(3)  //O2优化开启
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int mod=998244353;
const int MX=0x3f3f3f3f3f3f3f3f; 
//inline int read()                     //快读
//{
//    int xr=0,F=1; char cr;
//    while(cr=getchar(),cr<'0'||cr>'9') if(cr=='-') F=-1;
//    while(cr>='0'&&cr<='9')
//        xr=(xr<<3)+(xr<<1)+(cr^48),cr=getchar();
//    return xr*F;
//}
//void write(int x)                     //快写
//{
//    if(x<0) putchar('-'),x=-x;
//    if(x>9) write(x/10); putchar(x%10+'0');
//}
// 比 unordered_map 更快的哈希表
// #include <ext/pb_ds/assoc_container.hpp>
// using namespace __gnu_pbds;
// const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count();
// struct chash {
//     int operator()(int x) const { return x ^ RANDOM; }
// };
// typedef gp_hash_table<int, int, chash> hash_t;

template<int P>
struct MInt {
    int x;
    constexpr MInt() : x{} {}
    constexpr MInt(ll x) : x{norm(x % getMod())} {}

    static int Mod;
    constexpr static int getMod() {
        if (P > 0) {
            return P;
        } else {
            return Mod;
        }
    }
    constexpr static void setMod(int Mod_) {
        Mod = Mod_;
    }
    constexpr int norm(int x) const {
        if (x < 0) {
            x += getMod();
        }
        if (x >= getMod()) {
            x -= getMod();
        }
        return x;
    }
    constexpr int val() const {
        return x;
    }
    explicit constexpr operator int() const {
        return x;
    }
    constexpr MInt operator-() const {
        MInt res;
        res.x = norm(getMod() - x);
        return res;
    }
    constexpr MInt inv() const {
        assert(x != 0);
        return power(*this, getMod() - 2);
    }
    constexpr MInt &operator*=(MInt rhs) & {
        x = 1LL * x * rhs.x % getMod();
        return *this;
    }
    constexpr MInt &operator+=(MInt rhs) & {
        x = norm(x + rhs.x);
        return *this;
    }
    constexpr MInt &operator-=(MInt rhs) & {
        x = norm(x - rhs.x);
        return *this;
    }
    constexpr MInt &operator/=(MInt rhs) & {
        return *this *= rhs.inv();
    }
    friend constexpr MInt power(MInt a, ll b) {
        MInt res = 1;
        for (; b; b /= 2, a *= a) {
            if (b % 2) {
                res *= a;
            }
        }
        return res;
    }
    friend constexpr MInt operator*(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res *= rhs;
        return res;
    }
    friend constexpr MInt operator+(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res += rhs;
        return res;
    }
    friend constexpr MInt operator-(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res -= rhs;
        return res;
    }
    friend constexpr MInt operator/(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res /= rhs;
        return res;
    }
    friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
        ll v;
        is >> v;
        a = MInt(v);
        return is;
    }
    friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) {
        return os << a.val();
    }
    friend constexpr bool operator==(MInt lhs, MInt rhs) {
        return lhs.val() == rhs.val();
    }
    friend constexpr bool operator!=(MInt lhs, MInt rhs) {
        return lhs.val() != rhs.val();
    }
};

template<int V, int P>
constexpr MInt<P> CInv = MInt<P>(V).inv();

constexpr int P = 998244353;            //这里为自动模数
using mint = MInt<P>;           //mint是其定理的类型

const int N=2;

/*
 矩阵乘法 n * m 的矩阵 乘 m * k 的矩阵得到的结果是 n * k 的矩阵
 前一行(i) * 后一列(j) 的答案是结果矩阵的 (i, j) 位置的答案
 重点:推加速矩阵 将O(n) 的递推公式复杂度降至 logn
 可用于快速求解递推公式 点数少的邻接矩阵图中可用多少次幂表示第几步每个位置可能出现的个数 (要乘是否是起点)
 */

int n, m, K, d;

struct buff_matrix {
    mint b[N][N]; //大小不能是变量 必须是一个具体数字
    void init(int x) {
        memset(b, 0, sizeof b);
        for (int i = 0; i < N; i++) {
            b[i][i] = x;
        }
    }
    buff_matrix operator * (buff_matrix a) {
        buff_matrix ans;
        ans.init(0);
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                for (int k = 0; k < N; k++) {
                    ans.b[i][j] = (ans.b[i][j] + b[i][k]  * (a.b[k][j] ));
                }
            }
        }
        return ans;
    }
};

buff_matrix ksm(buff_matrix x, int p) {
    buff_matrix ans;
    ans.init(1);
    x = x * ans;
    while (p) {
        if (p & 1) {
            ans = ans * x;
        }
        p >>= 1;
        x = x * x;
    }
    return ans;
}

vector<PII>ve;
void icealsoheat(){

    cin>>n>>m;
    // int le=1;

    vector<PII>now;
    ve.clear();

    buff_matrix x1,x2,ans;
    x1.b[0][0]=x1.b[0][1]=x1.b[1][0]=1;
    x1.b[1][1]=2;
    x2.b[0][0]=x2.b[0][1]=0;
    x2.b[1][0]=1,x2.b[1][1]=2;

    ans.b[0][0]=ans.b[0][1]=1;
    ans.b[1][0]=ans.b[1][1]=0;

    for(int i=1;i<=m;i++){

        int x,y;
        cin>>x>>y;

        now.push_back({min(x,y),max(x,y)-1});

    }

    sort(now.begin(),now.end());

    int l,r;
    l=r=0;

    for(auto [x,y]:now){

        if(x>r){
            if(r!=0){
                ve.push_back({l,r});
            }
            l=x,r=y;
        }
        else r=max(r,y);

    }

    if(l!=0)ve.push_back({l,r});


    ve.push_back({n+1,n+1});

    int le=0;

    for(auto [x,y]:ve){

        int len=x-le-1;
        if(len&&le){
            ans=ans*x2*ksm(x1,len-1);
            // ans=ans*ksm(x1,len-1);
        }
        else if(len){
            ans=ans*ksm(x1,len);
        }
        le=y;

    }

    cout<<ans.b[0][0]<<"\n";
    
}
signed main(){
    ios::sync_with_stdio(false);          //int128不能用快读!!!!!!
    cin.tie();
    cout.tie();
    int _yq;
    _yq=1;
    cin>>_yq;
    while(_yq--){
        icealsoheat();
    }
}
//
//⠀⠀⠀             ⠀⢸⣿⣿⣿⠀⣼⣿⣿⣦⡀
//⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀ ⠀⢸⣿⣿⡟⢰⣿⣿⣿⠟⠁
//⠀⠀⠀⠀⠀⠀⠀⢰⣿⠿⢿⣦⣀⠀⠘⠛⠛⠃⠸⠿⠟⣫⣴⣶⣾⡆
//⠀⠀⠀⠀⠀⠀⠀⠸⣿⡀⠀⠉⢿⣦⡀⠀⠀⠀⠀⠀⠀ ⠛⠿⠿⣿⠃
//⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣦⠀⠀⠹⣿⣶⡾⠛⠛⢷⣦⣄⠀
//⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣧⠀⠀⠈⠉⣀⡀⠀ ⠀⠙⢿⡇
//⠀⠀⠀⠀⠀⠀⢀⣠⣴⡿⠟⠋⠀⠀⢠⣾⠟⠃⠀⠀⠀⢸⣿⡆
//⠀⠀⠀⢀⣠⣶⡿⠛⠉⠀⠀⠀⠀⠀⣾⡇⠀⠀⠀⠀⠀⢸⣿⠇
//⢀⣠⣾⠿⠛⠁⠀⠀⠀⠀⠀⠀⠀⢀⣼⣧⣀⠀⠀⠀⢀⣼⠇
//⠈⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠋⠙⠛⠛⠛⠛⠛⠁
//⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣾⡿⠋⠀
//⠀⠀⠀⠀⠀⠀⠀⠀⢾⠿⠋⠀
//

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 303ms
memory: 8328kb

input:

1408
999999987 100000
793040645 793040645
405719679 405719686
109446201 109446201
966244831 966244831
649934379 649934388
270235074 270235080
475603749 475603754
517746359 517746359
692479018 692479026
620056281 620056289
479316573 479316580
99301874 99301874
197649180 197649188
266341447 266341449
...

output:

991600316
319234130
93841910
206794274
263051780
82690092
131084460
239778094
709347248
326810262
294182113
972258718
740886273
876778123
908531500
401101074
43928585
129509578
494010178
667853498
702904367
522176720
720297418
956798992
931058784
227927814
489184304
815395422
760542660
383948722
138...

result:

ok 1408 lines