zoukankan      html  css  js  c++  java
  • 整体二分合集

    搞了一下整体二分,说一下自己的体会.

    其实我个人感觉,整体二分和cdq分治在感觉上差不多,写起来其实区别也不大.整体二分其实算是二分答案的升级版,二分答案后对所有询问进行分类,然后用cdq分治中的操作进行询问排序,然后存答案输出.大体上是这样的一个算法.

    区间二分有的时候可以省略一些复杂的数据结构,所以还是很资瓷的啊.

    k大数查询:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<complex>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    #define mp make_pair
    #define cp complex<db> 
    #define enter puts("")
    #define int long long
    const long long INF = 1LL << 60;
    const double eps = 1e-8;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    struct node
    {
        int kind,l,r,v,num,c,ans;
    }a[50005];
    int n,m;
    struct tree
    {
        int v,lazy;
        bool p;
    }t[131072];
    bool cmp1(node x,node y)
    {
        return x.c < y.c;
    }
    bool cmp2(node x,node y)
    {
        return x.num < y.num;
    }
    /*void push_down(int o,int l,int r)
    {
        if(t[o].p == true)
        {
            t[o].p = false;
            t[o >> 1].v = t[o >> 1 | 1].v = 0;
            t[o >> 1].lazy = t[o >> 1 | 1].lazy = 0;
            t[o >> 1].p = t[o >> 1 | 1].p = true;
            return;
        }
        if(t[o].lazy != 0)
        {
            int mid = (l + r) >> 1;
            t[o >> 1].lazy = t[o >> 1 | 1].lazy = t[o].lazy;
            t[o >> 1].lazy = (mid - l + 1) * t[o].lazy;
            t[o >> 1 | 1].lazy = (r - l) * t[o].lazy;
            t[o].lazy = 0;
        }
    }*/
    void push_down(int num,int l,int r){
        if(l==r)return;
        if(t[num].p){//更新儿子; 
            t[num*2].v=t[num*2+1].v=0;
            t[num*2].lazy=t[num*2+1].lazy=0;
            t[num*2].p=t[num*2+1].p=1;
            t[num].p=0;
        }
        int mid=(l+r)/2;
        t[num*2].v+=(mid-l+1)*t[num].lazy;
        t[num*2+1].v+=(r-(mid+1)+1)*t[num].lazy;
        t[num*2].lazy+=t[num].lazy;
        t[num*2+1].lazy+=t[num].lazy;
        t[num].lazy=0;
    }
    void init(int num,int l,int r,int x,int y)
    {
        push_down(num,l,r);
        if(x == l && r == y)
        {
            t[num].v += (r - l + 1) * 1;
            t[num].lazy += 1;
            return;
        }
        int mid = (l + r) >> 1;
        if(y <= mid)
        init(num << 1,l,mid,x,y);
        else if(x > mid)
        init(num << 1 | 1,mid + 1,r,x,y);
        else
        {
            init(num << 1,l,mid,x,mid);
            init(num << 1 | 1,mid + 1,r,mid + 1,y);
        }
        t[num].v = t[num << 1].v + t[num << 1 | 1].v;
    }
    int outit(int num,int l,int r,int x,int y)
    {
        push_down(num,l,r);
        if(x == l && r == y) return t[num].v;
        int mid = (l + r) >> 1;
        if(y <= mid)
        return outit(num << 1,l,mid,x,y);
        else if(x > mid)
        return outit(num << 1 | 1,mid + 1,r,x,y);
        else
        {
            return outit(num << 1,l,mid,x,mid) + outit(num << 1 | 1,mid + 1,r,mid + 1,y);
        }
    }
    /*int outit(int num,int l,int r,int x,int y){
        push_down(num,l,r);
        if(x<=l&&r<=y)return t[num].v;
        int mid=l+r>>1;
        int ans=0;
        if(mid  >=x)ans+=outit(num<<1,l,mid  ,x,y);
        if(mid+1<=y)ans+=outit(num<<1|1,mid+1,r,x,y);
        return ans;
    }*/
    void solve(int l,int r,int x,int y)
    {
    //    cout<<l<<" "<<r<<" "<<x<<" "<<y<<endl;
        if(l == r)
        {
            duke(i,x,y)
            a[i].ans = l;
            return;
        }
        int mid = (l + r) >> 1;
        int L = 0,R = y;
        t[1].v = t[1].lazy = 0;
        t[1].p = 1;
        for(int i = x;i <= y;i++)
        {
            if(a[i].kind == 1)
            {
                if(a[i].v <= mid)
                a[i].c = ++L;
                else
                {
                    a[i].c = ++ R;
                    init(1,1,n,a[i].l,a[i].r);
                }
            }
            else
            {
                int temp = outit(1,1,n,a[i].l,a[i].r);
                if(temp < a[i].v)
                {
                    a[i].v -= temp;
                    a[i].c = ++L;
                }
                else
                a[i].c = ++R;
            }
        }
        sort(a + x,a + y + 1,cmp1);
        solve(l,mid,x,x + L - 1);
        solve(mid + 1,r,x + L,y);
    }
    main()
    {
    //    freopen("3332.in","r",stdin);
        read(n); read(m);
        duke(i,1,m)
        {
            read(a[i].kind); read(a[i].l);
            read(a[i].r);read(a[i].v);
            a[i].num = i;
        }
        solve(-n,n,1,m);
        sort(a + 1,a + m + 1,cmp2);
        duke(i,1,m)
        {
            if(a[i].kind == 2)
            {
                printf("%d
    ",a[i].ans);
            }
        }
        return 0;
    }

    [POI2011]MET-Meteors:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;i++)
    #define lv(i,a,n) for(register int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 300005;
    int l[N],r[N],val[N];
    int n,m,tmp[N],k,t,ans[N],id[N],p[N];
    ll tr[N];
    vector <int> a[N];
    bool mark[N];
    int lowbit(int x)
    {
        return x & -x;
    }
    ll query(int x)
    {
        ll tmp = 0;
        while(x)
        {
            tmp += tr[x];
            x -= lowbit(x);
        }
        return tmp;
    }
    void add(int x,int v)
    {
        while(x <= m)
        {
            tr[x] += v;
            x += lowbit(x);
        }
    }
    void opera(int g,int f)
    {
        if(l[g] <= r[g])
        {
            add(l[g],f * val[g]);
            add(r[g] + 1,f * (-val[g]));
        }
        else
        {
            add(1,f * val[g]);
            add(r[g] + 1,f * (-val[g]));
            add(l[g],f * val[g]);
        }
    }
    void solve(int l,int r,int L,int R)
    {
        if(l > r) return;
        if(L == R)
        {
            duke(i,l,r)
            ans[id[i]] = L;
            return;
        }
        int mid = (L + R) >> 1;
        while(t <= mid) t++,opera(t,1);
        while(t > mid) opera(t,-1),t--;
        int cnt = 0,now;
        ll tot;
        duke(i,l,r)
        {
            tot = 0;
            now = id[i];
            for(int j = 0;j < (int)a[now].size();j++)
            {
                tot += query(a[now][j]);
                if(tot >= p[now]) break;
            }
            if(tot >= p[now]) mark[now] = 1,cnt++;
            else
            mark[now] = 0;
        }
        int l1 = l,l2 = l + cnt;
        duke(i,l,r)
        {
            if(mark[id[i]]) tmp[l1++] = id[i];
            else
            tmp[l2++] = id[i];
        }
        duke(i,l,r)
        id[i] = tmp[i];
        solve(l,l1 - 1,L,mid);
        solve(l1,l2 - 1,mid + 1,R);
    }
    int main()
    {
        read(n);read(m);
        duke(i,1,m)
        {
            int x;
            read(x);
            a[x].push_back(i);
        }
        duke(i,1,n)
        read(p[i]);
        read(k);
        duke(i,1,k)
        {
            read(l[i]);
            read(r[i]);
            read(val[i]);
        }
        k++;
        l[k] = 1; r[k] = m;val[k] = INF;
        duke(i,1,n)
        id[i] = i;
        solve(1,n,1,k);
        duke(i,1,n)
        {
            if(ans[i] != k)
            printf("%d
    ",ans[i]);
            else
            puts("NIE");
        }
        return 0;
    }

    [国家集训队]矩阵乘法:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<complex>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    #define mp make_pair
    #define cp complex<db>
    #define enter puts("")
    const long long INF = 1LL << 60;
    const double eps = 1e-8;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 510,Q = 60005;
    struct node
    {
        int x,y,v;
        bool operator < (const node &oth) const
        {
            return v < oth.v;
        }
    }mat[N * N];
    int mcnt,id[Q];
    int n,q;
    struct BIT
    {
        int c[N][N];
        int n;
        BIT()
        {
            clean(c);
            n = 0;
        }
        int lowbit(int x)
        {
            return x & -x;
        }
        void add(int x,int y,int v)
        {
            for(int i = x;i <= n;i += lowbit(i))
            {
                for(int j = y;j <= n;j += lowbit(j))
                {
                    c[i][j] += v;
                }
            }
        }
        int query(int x,int y)
        {
            int ans = 0;
            for(int i = x;i > 0;i -= lowbit(i))
            {
                for(int j = y;j > 0;j -= lowbit(j))
                {
                    ans += c[i][j];
                }
            }
            return ans;
        }
        int sub(int x1,int y1,int x2,int y2)
        {
            int ans = query(x2,y2);
            ans -= query(x1 - 1,y2) + query(x2,y1 - 1);
            ans += query(x1 - 1,y1 - 1);
            return ans;
        }
    }bit;
    struct events
    {
        int x1,x2,y1,y2,k;
        void input()
        {
            read(x1);read(y1);
            read(x2);read(y2);
            read(k);
        }
    }qu[Q];
    int ans[Q],cur[Q];
    int t1[Q],t2[Q];
    int bcount(events a)
    {
        return bit.sub(a.x1,a.y1,a.x2,a.y2);
    }
    void solve(int l,int r,int x,int y)
    {
        // cout<<l<<" "<<r<<" "<<x<<" "<<y<<endl;
        if(x > y) return;
        if(l == r)
        {
            duke(i,x,y)
            ans[id[i]] = mat[l].v;
            return;
        }
        int mid = (l + r) >> 1;
        duke(i,l,mid)
        {
            bit.add(mat[i].x,mat[i].y,1);
        }
        int cnt1 = 0,cnt2 = 0;
        for(int i = x;i <= y;i++)
        {
            int u = id[i];
            int s = cur[u] + bcount(qu[u]);
            if(s >= qu[u].k) t1[++cnt1] = u;
            else t2[++cnt2] = u,cur[u] = s;
        }
        int qcnt = x - 1;
        duke(i,1,cnt1)
        id[++qcnt] = t1[i];
        duke(i,1,cnt2)
        id[++qcnt] = t2[i];
        for(int i = l;i <= mid;i++)
        bit.add(mat[i].x,mat[i].y,-1);
        solve(l,mid,x,x + cnt1 - 1);
        solve(mid + 1,r,x + cnt1,y);
    }
    int main()
    {
        // freopen("1527.in",?"r",stdin);
        read(n); read(q);
        bit.n = n;
        duke(i,1,n)
        {
            duke(j,1,n)
            {
                int x;
                read(x);
                mat[++mcnt] = (node){i,j,x};
            }
        }
        sort(mat + 1,mat + mcnt + 1);
        duke(i,1,q)
        {
            qu[i].input();
        }
        duke(i,1,q)
        {
            id[i] = i;
        }
        solve(1,mcnt,1,q);
        duke(i,1,q)
        {
            printf("%d
    ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    最牛B的编码套路
    CRM运维工程师主要职责
    SQL ROUND函数用法
    VMware不能完全卸载问题
    如何建立真正支持业务的高效运维体系?
    【TensorFlow】tf.nn.softmax_cross_entropy_with_logits的用法
    L1正则化与L2正则化详解及解决过拟合的方法
    TensorFlow学习笔记之--[tf.clip_by_global_norm,tf.clip_by_value,tf.clip_by_norm等的区别]
    TensorFlow学习笔记之--[compute_gradients和apply_gradients原理浅析]
    Windows10+Tensorflow1.12-gpu+CUDA+cudnn+Anaconda3.5+Pycharm3.5 离线GPU开发环境搭建
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10118509.html
Copyright © 2011-2022 走看看