• 18寒假第五测


    第一题 线段树

    树状数组存差b[i] = a[i]-a[i-1],反正是单点查询,我为什么没想到。。。很傻的用线段树

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 100005
    #define ll long long 
    int n, m, a[maxn];
    struct SegmentTree{
        struct node{
            ll sum;
            int lazy; 
        };
        node Tree[maxn << 2];
        
        #define ls l, m, v << 1
        #define rs m+1, r, v << 1 | 1
        
        void updata(int v){
            Tree[v].sum = Tree[v << 1].sum + Tree[v << 1 | 1].sum;
        }
        
        void push_down(int l, int r, int v){
            int m = (l + r) >> 1;
            Tree[v << 1].sum += Tree[v].lazy * (m - l + 1) * 1LL;
            Tree[v << 1].lazy += Tree[v].lazy;
            Tree[v << 1 | 1].sum += Tree[v].lazy * (r - m) * 1LL;
            Tree[v << 1 | 1].lazy += Tree[v].lazy;
            
            Tree[v].lazy = 0;
        }
        void build(int l = 1, int r = n, int v = 1){
            if(l == r) Tree[v].sum = a[l], Tree[v].lazy = 0;
            else {
                int m = (l + r) >> 1;
                build(ls);
                build(rs);
                updata(v);
            }
        }
        
        void modify(int x, int L, int R, int l = 1, int r = n, int v = 1){
            if(l >= L && r <= R){
                Tree[v].sum += x * (r - l + 1) * 1LL;
                Tree[v].lazy += x;
            }
            else {
                if(Tree[v].lazy) push_down(l, r, v);
                int m = (l + r) >> 1;
                if(L <= m)modify(x, L, R, ls);
                if(R > m)modify(x, L, R, rs);
                updata(v);
            }
        }
        
        ll query(int x,int l = 1, int r = n, int v = 1){
            if(l == r)return Tree[v].sum;
            else {
                if(Tree[v].lazy) push_down(l, r, v);
                int m = (l + r) >> 1;
                if(x <= m) return query(x, ls);
                if(x > m)return query(x, rs);
            }
        }
    };
    SegmentTree Tr;
    int main(){
        freopen("bit.in","r",stdin);
        freopen("bit.out","w",stdout);
        cin>>n;
        for(int i = 1; i <= n; i++)scanf("%d", a + i);
        Tr.build();
        cin>>m;
        for(int i = 1; i <= m; i++){
            string opt;
            cin>>opt;
            if(opt[0] == 'm'){
                int l, r, val;
                scanf("%d%d%d",&l,&r,&val);
                Tr.modify(val, l, r);
            }
            else {
                int x;
                scanf("%d",&x);
                cout<<Tr.query(x)<<endl;
            }
        }
    }

    第二题:一道巨恶心的线段树取模,一般公式知道了就没问题,但lazy乘起来是long long ,一堆人看了一晚上。。。第二天又忘了long long

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 100005
    #define ll long long 
    int n, m, a[maxn];
    int mod = 1000000007;
    struct SegmentTree{
        struct node{
            ll sum,lazy[2];
        };
        node Tree[maxn << 2];
        
        #define ls l, m, v << 1
        #define rs m+1, r, v << 1 | 1
        
        void updata(int v){
            Tree[v].sum = ( Tree[v << 1].sum % mod + Tree[(v << 1) | 1].sum % mod ) % mod;
            
        }
        
        void push_down(int l, int r, int v){
            if(Tree[v].lazy[0] == 1 && Tree[v].lazy[1] == 0)return;
            int m = (l + r) >> 1;
            int A = Tree[v].lazy[0], B = Tree[v].lazy[1];
            modify(A, B, l, m, ls);
            modify(A, B, m+1, r, rs);        
            Tree[v].lazy[0] = 1, Tree[v].lazy[1] = 0;
        }
        void build(int l = 1, int r = n, int v = 1){
            if(l == r) Tree[v].sum = a[l], Tree[v].lazy[0] = 1, Tree[v].lazy[1] = 0;
            else {
                int m = (l + r) >> 1;
                build(ls);
                build(rs);
                updata(v);
                Tree[v].lazy[0] = 1, Tree[v].lazy[1] = 0;
            }
        }
        
        void modify(int A, int B, int L, int R, int l = 1, int r = n, int v = 1){
            if(l >= L && r <= R){
                ll q = Tree[v].sum;
                Tree[v].sum = (q * (A % mod) + 1LL * (B % mod) * (r - l + 1 )) % mod;
                ll olda = Tree[v].lazy[0], oldb = Tree[v].lazy[1];
                Tree[v].lazy[0] = A * olda % mod , Tree[v].lazy[1] = ( A * oldb + B )% mod;
                //printf("olda = %d A = %d newa = %d
    ",olda,A, Tree[v].lazy[0]);
            }
            else {
                push_down(l, r, v);
                int m = (l + r) >> 1;
                if(L <= m)modify(A, B, L, R, ls);
                if(R > m)modify(A, B, L, R, rs);
                updata(v);
            }
            
        }
        
        ll query(int L,int R,int l = 1, int r = n, int v = 1){
            if(l >= L && r <= R)return Tree[v].sum ;
            else {
                push_down(l, r, v);
                int m = (l + r) >> 1;
                ll ans = 0;
                if(L <= m) ans = (ans + query(L, R, ls) % mod) % mod;
                if(R > m)ans = (ans % mod + query(L, R, rs)% mod) % mod;
                return ans;
            }
        }
    };
    SegmentTree Tr;
    int main(){
        freopen("linear.in","r",stdin);
        freopen("linear.out","w",stdout);
        cin>>n;
        for(int i = 1; i <= n; i++)scanf("%d", a + i);
        Tr.build();
        cin>>m;
        for(int i = 1; i <= m; i++){
            string opt;
            cin>>opt;
            if(opt[0] == 'm'){
                int l, r, A, B;
                scanf("%d%d%d%d",&l,&r,&A,&B);
                Tr.modify(A, B, l, r);
                
            }
            else {
                int l, r;
                scanf("%d%d",&l,&r);
                cout<<Tr.query(l, r)<<endl;
            }
        }
    }

    第三题 裸的splay扳子,很少找到卿学姐有这么接地气的板子,就搬过了,但splay的地方还是写挂了。。。

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 100005
    #define ll long long 
    int n, m, a[maxn], val[maxn];
    struct SplayTree{
        int siz[maxn], fa[maxn], son[maxn][2];
        int tot, root;
        void update(int nd){
            siz[nd] = siz[son[nd][0]] + siz[son[nd][1]] + 1;
        }
        void init(){
            siz[0] = 0;
            tot = 0;
            root = build(0, 1, n);
        }
        int build(int f, int l,int r){
            
            if(l > r)return 0;
            int nd = ++tot;
            fa[nd] = f;
            int m = (l + r) >> 1;
            son[nd][0] = build(nd, l, m - 1);
            son[nd][1] = build(nd, m + 1, r);
            val[nd] = a[m];
            update(nd);
            //printf("nd = %d s[0] = %d, s[1] = %d, l = %d, r = %d val = %d
    ",nd,son[nd][0],son[nd][1],l,r,val[nd]);
            return nd;
            
        }
        int find(int pos){
            int nd = root;
            while(1){
                int ls = siz[son[nd][0]];
                if(pos <= ls)nd = son[nd][0];
                else if(pos >= ls + 2){
                    pos -= ls + 1;
                    nd = son[nd][1];
                }
                else return nd;
                
            }
        }
        int query(int pos){
            return val[find(pos)];
        }
        void rotate(int x,int d){
            int y = fa[x];
            son[y][d^1] = son[x][d];
            if(son[x][d])fa[son[x][d]] = y;
            fa[x] = fa[y];
            if(fa[y]){
                if(y == son[fa[y]][d])son[fa[y]][d] = x;
                else son[fa[y]][d^1] = x;
            }
            son[x][d] = y, fa[y] = x;
            update(y), update(x);
        }
        void splay(int x,int target = 0){
            while(fa[x] != target){
                int y = fa[x];
                if(x == son[y][0]){
                    if(fa[y] != target && y == son[fa[y]][0])
                        rotate(y, 1);
                    rotate(x, 1);
                }
                else {
                    if(fa[y] != target && y == son[fa[y]][1])
                        rotate(y, 0);
                    rotate(x, 0);
                }
            }
            if(!target)root = x;
        }
        void erase(int pos){
            int lnd = find(pos - 1), rnd = find(pos + 1);
            splay(lnd);
            splay(rnd, lnd);
            son[rnd][0] = 0;
            update(rnd), update(lnd);
        }
    };
    SplayTree Tr;
    int main(){
        freopen("sequence.in","r",stdin);
        freopen("sequence.out","w",stdout);
        cin>>n>>m;
        for(int i = 2; i <= n + 1; i++)scanf("%d", a + i);
        a[1] = 0, a[n + 2] = 0;
        n += 2;
        Tr.init();
        
        for(int i = 1; i <= m; i++){
            string opt;
            int pos;
            cin>>opt;
            scanf("%d",&pos);
            if(opt[0] == 'D')Tr.erase(pos + 1);
            else printf("%d
    ",Tr.query(pos + 1));
        }
        
    }
  • 相关阅读:
    如何让WPF程序用上MVVM模式
    wpf开源界面收集
    WPF界面框架的设计
    WPF数据验证
    WPF实用知识点
    wpf的MVVM框架
    数据库中树形结构的表的设计
    ASP.NET MVC 分部视图
    好用的 Visual Studio插件
    ASP.NET MVC3中Controller与View之间的数据传递总结
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/8445365.html
Copyright © 2020-2023  润新知