牛オフより多くの学校合宿第九フィールドJ - 対称絵画(ソート)

J - 対称絵画

問題の意味

あなた\(\ N-)長方形、下は左\((1-I、\ L_iを)\) 右上\((I、\ R_iとの)\)ラインを見つけるために、\(Lの\)するために平行に(\しますX \)軸を、そのように、これらの矩形は、に応じて\(1- \)対称、非対称の部分が削除、最大の対称的なパターン面積はどのくらいですって?

考え

対称の主軸は、それが小から大列挙し、列挙することである\(L_iを、(L_iをR_iを+)/ 2、R_iを\) 対称の3つの軸の位置を。
これは、矩形領域を維持する方法を列挙してみましょう。

  • まず、することができます(L_iを* 2、* 2 R_iと\)を\エラーが真ん中を取って発生しないように、。
  • 次いでとして標識された三つの位置\(1:L_iを、\ \ \ 2:(L_iを+ R_iを)/ 2、\ \ \ 3:R_iを\)
  • 小の位置に応じて大きいために
  • \(A及びB \)タグ、加算または減算する\(ANS \)現在対称領域:
    もしヒットフラグ、1 \(1、A ++ \)
    2、もしヒットフラグ\(2、A-- 、B ++ \)
    3、ヒットフラグ場合\(3、B - 。\)
    \(ANS = + ANS(W_i - 1-W_ {I})*(AB&)* 2 \) 以下のみ矩形用分析
    • \(L_iを\ルW_i \ル(L_iをR_iを+)/ 2 \) 対称大きい領域、\(ANS = + ANS(W_i - 1-W_ {I})* 2 \)。
    • \((L_iを+ R_iを)/ 2 \ルW_i \ルR_iを\) 対称面積が小さくなり、\(ANS = ANS - (W_i - W_ {I- 1})* 2 \) 以来オーバー添加前に\( (L_iをR_iを+)/ 2 \) \(L_iを\)領域、領域が現在必要とされている(w_i \)\\(R_iを\)領域、その後、上記減算\を((w_i - W_ { I-1})* 2 \ )
    • \(R_iを\ルW_i \) L:に等しい面積\(0 \) 次いで\(B - \)その上に。
  • 覚えておくべき最終的な答え\(最大/ 2 \)
    私はクラスの対称軸を列挙したかったが、常にシンプルかつ独創的な、維持する方法を理解し、以降のコードの首長のいくつかを見ていないと思ったゲームを。とにかく、私は考えています。それを維持します。

    コード

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 3e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

int n, m;
int cas, tol, T;
struct Node{
    ll w;
    int id;
    bool operator < (Node const & a){
        return w < a.w;
    }
}node[maxn*4];

int main() {
    scanf("%d", &n);
    ll l, r;
    int cnt = 0;
    for(int i = 1; i <= n; i++){
        scanf("%lld%lld", &l, &r);
        l *= 2;
        r *= 2;
        node[++cnt] = {l, 1};
        node[++cnt] = {(l+r)/2, 2};
        node[++cnt] = {r, 3};
    }
    sort(node+1, node+cnt+1);
    ll a = 0, b = 0, ans = 0, Max = 0;
    for(int i = 1; i <= cnt; i++){
        ans += (node[i].w - node[i-1].w)*(a-b)*2;       \\也可以这边不乘,最后就不用除了
        if(node[i].id == 1)
            a++;
        if(node[i].id == 2){
            a--;b++;
        }
        if(node[i].id == 3)
            b--;
        Max = max(Max, ans);
    }
    printf("%lld\n", Max/2);
    return 0;
}

おすすめ

転載: www.cnblogs.com/zhuyou/p/11365730.html