zoukankan      html  css  js  c++  java
  • GYM

    题意:

      一个n*n的棋盘,有m个主教。每个主教都有自己的权值p。给出一个值C,在棋盘中找到一个最大点集。这个点集中的点在同一条对角线上且对于点集中任意两点(i,j),i和j之间的主教数(包括i,j)不小于pi^2+pj^2+C。

    题解:

      对角线有2个方向,每个方向有2*n-1条对角线。一共时4*n-2条。每个点都在2条对角线上。

      对于在同一对角线上的点(i,j)若满足i-j+1>=pi^2+pj^2+C即-j-pj^2>=pi^2+C-i-1(i>j)即可。

      那么将同一对角线上的点按x坐标排序。将每个点的信息整合到一起离散化,最后用树状数组维护每个点前面满足-j-pj^2>=pi^2+C-i-1的最大值。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, ll> P;
    const int maxn = 1e5+10;
    int t;
    int n, m;
    ll c;
    int u, v;
    ll p;
    int cnt;
    int ans;
    ll _sort[maxn<<1];
    int tree[maxn<<1];
    struct node {
        int x;
        ll val;
        node(int a, ll b) {
            x = a; val = b;
        }
    };
    vector<P> bs[2][maxn<<1]; 
    void update(int x, int val) {
        while(x <= cnt) {
            tree[x] = max(tree[x], val);
            x += x&(-x); 
        }
    }
    int sum(int x) {
        int res = 0;
        while(x > 0) {
            res = max(res, tree[x]);
            x -= x&(-x);
        }
        return res;
    }
    int main() {
        freopen("bishops.in","r",stdin);
        scanf("%d", &t);
        while(t--) {
            ans = 0;
            scanf("%d%d%lld", &n, &m, &c);
            for(int i = 0; i < 2; i++) 
            for(int j = 1; j < 2*n; j++) bs[i][j].clear();
            while(m--) {
                scanf("%d%d%lld", &u, &v, &p);
                p *= p;
                bs[0][u+v-1].push_back(P(u, p));
                bs[1][u-v+n].push_back(P(u, p));
            }
            for(int i = 0; i < 2; i++) 
            for(int j = 1; j < 2*n; j++) sort(bs[i][j].begin(), bs[i][j].end());
            
            for(int i = 0; i < 2; i++)
            for(int j = 1; j < 2*n; j++) {
                int len = bs[i][j].size();
                cnt = 0;
                for(int k = 0; k < len; k++) {
                    int x = bs[i][j][k].first;
                    ll p = bs[i][j][k].second;
                    _sort[cnt++] = -p-x;
                    _sort[cnt++] = p+c-x-1;
                }
                sort(_sort, _sort+cnt);
                cnt = unique(_sort, _sort+cnt)-_sort;
                for(int k = 1; k <= cnt; k++) tree[k] = 0;
                for(int k = 0; k < len; k++) {
                    int x = bs[i][j][k].first;
                    ll p = bs[i][j][k].second;
                    int id = cnt-(lower_bound(_sort, _sort+cnt, p+c-x-1)-_sort);
                    int tmp = sum(id);
                    ans = max(ans, tmp+1);
                    id = cnt-(lower_bound(_sort, _sort+cnt, -p-x)-_sort);
                    update(id, tmp+1);
                }
            }
            printf("%d
    ", ans);
        }
    } 
    View Code
  • 相关阅读:
    flock对文件锁定读写操作的问题 简单
    hdu 2899 Strange Fuction(二分)
    hdu 2199 Can you solve this equation? (二分)
    poj 3080 Blue Jeans (KMP)
    poj 2823 Sliding Window (单调队列)
    poj 2001 Shortest Prefixes (trie)
    poj 2503 Babelfish (trie)
    poj 1936 All in All
    hdu 3507 Print Article (DP, Monotone Queue)
    fzu 1894 志愿者选拔 (单调队列)
  • 原文地址:https://www.cnblogs.com/Pneuis/p/8900834.html
Copyright © 2011-2022 走看看