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;
    }
  • 相关阅读:
    OLAP ODS项目的总结 平台选型,架构确定
    ORACLE ORA12520
    ORACLE管道函数
    ORACLE RAC JDBC 配置
    ORACLE RAC OCFS连接产生的错误
    ORACLE 启动和关闭详解
    OLAP ODS项目的总结 起步阶段
    ORACLE RAC 配置更改IP
    ORACLE RAC OCR cann't Access
    ORACLE RAC Debug 之路 CRS0184错误与CRS初始化
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10118509.html
Copyright © 2011-2022 走看看