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;
}