zoukankan      html  css  js  c++  java
  • 19.9.21 考试总结

      

    今天的题比较水... 班上的大佬们都AK了 我这种蒟蒻就完全不会矩阵快速幂

    我永远恨矩阵快速幂

    然后这道题还是比较简单的 就是维护区间连续最大和

    线段树维护一下就可以了

    代码

    #include <bits/stdc++.h>
    #define oo 2 * 1e9
    using namespace std;
    
    const int N = 5 * 1e5 + 5; 
    int n,m,lmax[4 * N],rmax[4 * N],f[4 * N],a[N],g[4 * N],sum[4 * N];
    struct data{
        int lma,rma,s,sm;
        data(int lma = 0,int rma = 0,int s = 0,int sm = 0): lma(lma),rma(rma),s(s),sm(sm) { }
    };
    
    void update(int o) {
        
        g[o] = max(g[2 * o], g[2 * o + 1]); sum[o] = sum[2 * o] + sum[2 * o + 1];
        lmax[o] = lmax[2 * o]; rmax[o] = rmax[2 * o + 1];
        f[o] = max(f[2 * o], f[2 * o + 1]); f[o] = max(f[o], rmax[2 * o] + lmax[2 * o + 1]);
        lmax[o] = max(lmax[o], sum[2 * o] + lmax[2 * o + 1]);
        rmax[o] = max(rmax[o], sum[2 * o + 1] + rmax[2 * o]);
        f[o] = max(f[o], max(lmax[o], rmax[o]));
    }
    
    void build(int o,int l,int r) {
        
        if(l == r) {
            sum[o] = a[l];
            g[o] = a[l];
            rmax[o] = max(0, a[l]); lmax[o] = max(0, a[l]);
            f[o] = max(0,a[l]);
            return ;
        }
        int mid = (l + r) >> 1;
        build(2 * o, l, mid);
        build(2 * o + 1, mid + 1, r);
        update(o);
    }
    
    void Init( ) {
        
        scanf("%d%d",& n,& m);
        for(int i = 1;i <= n;i ++) scanf("%d",& a[i]);
        build(1, 1, n);
    }
    
    data query(int o,int l,int r,int L,int R) {
        
        if(l >= L && r <= R) return data(lmax[o], rmax[o], f[o], sum[o]);
        int mid = (l + r) >> 1;
        data q1,q2,q3; q1 = data(0, 0, 0, 0); q2 = data(0, 0, 0, 0); q3 = data(0, 0, 0, 0);
        int t1 = 0,t2 = 0;
         if(L <= mid) {
             q1 = query(2 * o, l, mid, L, R); t1 = 1;
         }
        if(mid < R) {
            q2 = query(2 * o + 1, mid + 1, r, L, R); t2 = 1;
        }
        if(! t1 && t2) return q2;
        if(t1 && ! t2) return q1;
        if(t1 && t2) {
            q3.lma = max(q1.lma, q3.lma); q3.rma = max(q3.rma, q2.rma);
            q3.s = max(q3.s, max(q1.s, q2.s)); q3.s = max(q3.s, q1.rma + q2.lma);
            q3.lma = max(q3.lma, q1.sm + q2.lma);
            q3.rma = max(q3.rma, q2.sm + q1.rma);
            q3.s = max(q3.s, max(q3.lma, q3.rma));
        } 
        return q3;
    }
    
    void modify(int o,int l,int r,int pos,int del) {
        
        if(l == r) {
            sum[o] = del;
            rmax[o] = max(0, del); lmax[o] = max(0, del);
            f[o] = max(0,del); g[o] = del;
            return ;
        }
        int mid = (l + r) >> 1;
        if(pos <= mid) modify(2 * o, l, mid, pos, del);
        else modify(2 * o + 1, mid + 1, r, pos, del);
        update(o);
    }
    
    int query_max(int o,int l,int r,int L,int R) {
        
        if(l >= L && r <= R) return g[o];
        int mid = (l + r) >> 1;
        int ans = -oo;
        if(L <= mid) ans = max(ans, query_max(2 * o, l, mid, L, R));
        if(mid < R) ans = max(ans, query_max(2 * o + 1, mid + 1, r, L, R));
        return ans;
    }
    
    inline int read( ) {
        
        int t = 1,ans = 0;
        char x; x = getchar( );
        while(x < '0' || x > '9') {
            if(x == '-') t = -1;
            x = getchar( );
        }
        while(x >= '0' && x <= '9') {
            ans = ans * 10 + x - '0';
            x = getchar( );
        }
        return ans * t;
    }
    
    void Solve( ) {
        
        while(m --) {
            int opt,l,r;
            opt = read( );
            if(opt == 1) {
                l = read( ); r = read( );
                data ans = query(1, 1, n, l, r);
                if(ans.s == 0) ans.s = query_max(1, 1, n, l, r);
                printf("%d
    ",ans.s);
            }
            else {
                l = read( ); r = read( );
                a[l] = r;
                modify(1, 1, n, l, r);
            }
        }
    }
    
    int main( ) {
        
        freopen("BRS.in","r",stdin);
        freopen("BRS.out","w",stdout);
        Init( );
        Solve( );
    }

     

    这道题就是矩阵快速幂 然后借着这道题的机会我重新学习了一波矩阵快速幂...

    方程还是很简单的 就不说了 最重要的就是构造转移矩阵和初始矩阵 

    完了发现这是一道水水题 先把$dp[1],dp[2] ... dp[k]$预处理出来 

    然后转移矩阵 $1111$   初始矩阵 $dp[k]$

           $1000$      $dp[k - 1]$

           $0100$                 $dp[...]$

           $0010$                 $dp[2]$

           $0001$                 $dp[1]$          类似于这种

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 1e3 + 5;
    const ll MOD = 7777777;
    ll dp[N],s[20][5];
    ll K,n;
    struct Matrix {
        
        ll a[15][15];
    }h;
    
    void Moc(ll & a,ll b) {
        
        a = (a + b) % MOD;
    }
    
    Matrix pl(Matrix A,Matrix B) {
        
        Matrix c;
        for(int i = 1;i <= K;i ++) 
            for(int j = 1;j <= K;j ++) c.a[i][j] = 0;
        for(int i = 1;i <= K;i ++)
            for(int j = 1;j <= K;j ++) {
                for(int k = 1;k <= K;k ++)
                    Moc(c.a[i][j], 1ll * A.a[i][k] * B.a[k][j] % MOD);
            }
        return c;
    }
    
    void Init( ) {
        
        scanf("%d%d",& K,& n);
        dp[0] = 1;
        for(int i = 1;i <= K;i ++) {
            for(int k = 0;k < i;k ++) {
                Moc(dp[i], dp[k]);
            }
        }
        for(int i = 1;i <= K;i ++) {
            h.a[1][i] = 1;    
        }
        for(int j = 2;j <= K;j ++) h.a[j][j-1] = 1;
        for(int i = 1;i <= K;i ++) s[i][1] = dp[i];
    }
    
    Matrix fast_pow(Matrix A,int del) {
        
        Matrix ans;
        for(int i = 1;i <= K;i ++) 
            for(int j = 1;j <= K;j ++) {
                ans.a[i][j] = 0;
                if(i == j) ans.a[i][j] = 1;
            }
        for(;del;del >>= 1,A = pl(A, A))
            if(del & 1) ans = pl(ans, A);
        return ans;
    }
    
    void Solve( ) {
        
        h = fast_pow(h, n - K);
        ll ans = 0;
        for(int i = 1;i <= K;i ++) Moc(ans, h.a[1][i] * s[K + 1 - i][1] % MOD);
        printf("%lld
    ",ans);
    }
    
    int main( ) {
        
        freopen("fyfy.in","r",stdin);
        freopen("fyfy.out","w",stdout);
        Init( );
        Solve( );
    }

     ...这道题是扫描线的板子啊 而且数据范围这么小 就乱搞都可以过得

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int M = 10005;
    int n,q;
    ll ans = 0;
    int yy[M * 2];
    struct Event{
        int x,y1,y2;
        int d;
    };
    vector<Event>e;
    
    struct Node {
        
        int sum,cnt;
        Node * ls,* rs;
        
        void up(int l, int r){
            if(cnt) sum = yy[r] - yy[l - 1];
            else if(l != r)
                sum = ls -> sum + rs -> sum;
            else sum = 0;
        }
    }pool[M],* root,* tail = pool;
    
    Node *build(int l = 1, int r = q) {
        
        Node * nd = ++ tail;
        if(l == r) nd -> sum = 0, nd -> cnt = 0;
        else {
            int mid = (l + r) >> 1;
            nd -> ls = build(l, mid);
            nd -> rs = build(mid + 1, r);
            nd -> up(l, r);
        }
        return nd;
    }
    
    #define Ls l, mid, nd -> ls
    #define Rs mid+1, r, nd -> rs
    
    void modify(int L, int R, int d, int l = 1, int r = q, Node * nd = root) {
        
        if(L <= l && R >= r) nd -> cnt += d, nd -> up(l, r);
        else {
            int mid = (l + r) >> 1;
            if(L <= mid)  modify(L, R, d, Ls);
            if(R > mid)   modify(L, R, d, Rs);
            nd -> up(l, r);
        }
    }
    
    bool operator < (const Event & a, const Event & b) {
        
        return a.x < b.x;
    }
    
    inline int read( ) {
        
        int t = 1,ans = 0;
        char x; x = getchar( );
        while(x < '0' || x > '9') {
            if(x == '-') t = -1;
            x = getchar( );
        }
        while(x >= '0' && x <= '9') {
            ans = ans * 10 + x - '0';
            x = getchar( );
        }
        return ans * t;
    }
    
    void Init( ) {
        
        scanf("%d",& n);
        int cnt = 0,k = 0;
        for(int i = 1;i <= n;i ++){
            int x1,x2,y1,y2;
            x1 = read( ); y1 = read( ); 
            x2 = read( ); y2 = read( );
            e.push_back((Event){x1, y1, y2, 1});
            e.push_back((Event){x2, y1, y2, -1});
            yy[++ cnt] = y1; yy[++ cnt] = y2;
        }
        sort(yy + 1, yy + 1 + cnt);
        sort(e.begin( ), e.end( ));
        q = unique(yy + 1, yy + 1 + cnt) - yy - 1;
        root = build( );
    }
    
    void Solve( ) {
        
        for(int i = 0;i < 2 * n;i ++) {
            ll dx = i == 0 ? 0 : e[i].x - e[i - 1].x;
            ans += 1ll * root -> sum * dx;
            int p1 = find(yy + 1, yy + 1 + q, e[i].y1) - yy;
            int p2 = find(yy + 1, yy + 1 + q, e[i].y2) - yy;
            modify(p1 + 1, p2, e[i].d);
        }
        printf("%lld
    ", ans);
    }
    
    int main( ) {
        
        freopen("olddriver.in","r",stdin);
        freopen("olddriver.out","w",stdout);
        Init( );
        Solve( );
    }
  • 相关阅读:
    关于SQL批量插入数据方法比较
    Meta详细说明及使用方法
    【原创】自己写的用户控件的传值
    Windows 2003全面优化
    IT职位全面解析(软件类)
    NHibernate介绍
    获取到的客户端发送的文件的MIME内容类型的全部类型列
    C#如何编程方式获取计算机主板序列号
    XP下HTTP的403.9错误禁止访问:连接的用户过多如何解
    用户登录验证程序——VB.NET
  • 原文地址:https://www.cnblogs.com/Rubenisveryhandsome/p/9688752.html
Copyright © 2011-2022 走看看