zoukankan      html  css  js  c++  java
  • cf 526 F

    CF 526F

    一个N × N的地图上有N个棋子,每一行每一列都有且仅有一个 棋子。问有多少个正方形满足其内部的棋子数等于其边长

    SOLUTION:

    可以发现按x坐标把点排序后得出一个排列,求有多少个区间长度等于最大值减最少值。可以考虑分治,可以算出中心到左右区间的最大最小值,若最大最小值在同侧则可以枚举一端算出另一端再判断是否合法。若不同侧可以发现左最大右最小时r-l==max[l]-min[r],即l+max[l]==r+min[r],相互独立可以开桶判断。从中间往左枚举一端,发现满足左最大右最小的右端区间是单调的,因为最大值单调上升最小值单调下降,左端最大最小值变化,右端最小值必须更小最大值可以更大,判一下是否有答案即可。(转载自chunkitlau)

    仍然是注意细节,想清楚再写,尽量少犯错

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define maxn 300020
     7 #define inf 0x3f3f3f3f
     8 
     9 typedef long long ll;
    10 int a[maxn],mx[maxn],mn[maxn],n,num[maxn];
    11 ll ans;
    12 
    13 void solve(int l,int r){
    14     if ( l == r ) return;
    15     int mid = (l + r) >> 1;
    16     //========================mx和mn在mid两侧
    17     mx[mid] = mn[mid] = a[mid] , mx[mid + 1] = mn[mid + 1] = a[mid + 1];
    18     for (int i = mid + 2 ; i <= r ; i++){
    19         mn[i] = min(mn[i - 1],a[i]);
    20         mx[i] = max(mx[i - 1],a[i]);
    21     }
    22     for (int i = mid - 1 ; i >= l ; i--){
    23         mn[i] = min(mn[i + 1],a[i]);
    24         mx[i] = max(mx[i + 1],a[i]);
    25     }
    26     //注意加减1的细节
    27     for (int i = mid,j = mid + 1,k = mid + 1 ; i >= l ; i--){
    28         while ( k <= r && mx[i] >= mx[k] ) num[k - mid + mn[k]]++ , k++;
    29         while ( j <= min(k - 1,r) && mn[i] < mn[j] ) num[j - mid + mn[j]]-- , j++;
    30         if ( j > r ) break;
    31         if ( mx[i] + 1 >= mid - i + 1  ) ans += num[mx[i] + 1 - (mid - i + 1)];
    32     }    
    33     for (int i = mid + 1 ; i <= r ; i++) num[i - mid + mn[i]] = 0;
    34 
    35     
    36     for (int i = mid + 1 , j = mid , k = mid ; i <= r ; i++){
    37         while ( k >= l && mx[i] >= mx[k] ) num[mid - k + 1 + mn[k]]++ , k--;
    38         while ( j >= max(l,k + 1) && mn[i] < mn[j] ) num[mid - j + 1 + mn[j]]-- , j--;
    39         if ( j < l ) break;
    40         if ( mx[i] + 1 >= i - mid ) ans += num[mx[i] + 1 - (i - mid)];
    41     }
    42     for (int i = l ; i <= mid ; i++) num[mid - i + 1 + mn[i]] = 0;
    43     //========================mx和mn在mid同侧
    44     for (int i = mid ; i >= l ; i--){
    45         int x = mx[i] - mn[i] + i;
    46         if ( x <= r && x > mid && mx[x] <= mx[i] && mn[x] >= mn[i] ) ans++;
    47     }
    48     for (int i = mid + 1 ; i <= r ; i++){
    49         int x = i - (mx[i] - mn[i]);
    50         if ( x >= l && x <= mid && mx[x] <= mx[i] && mn[x] >= mn[i] ) ans++;
    51     }
    52     solve(l,mid) , solve(mid + 1,r);
    53 }
    54 int main(){
    55     freopen("input.txt","r",stdin);
    56     scanf("%d",&n);
    57     for (int i = 1 ; i <= n ; i++){
    58         int x,y;
    59         scanf("%d %d",&x,&y);
    60         a[x] = y;
    61     }
    62     solve(1,n);
    63     printf("%lld
    ",ans + n);
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    php if() 括号中为 真详解
    php 写入日志
    trim,rtrim,ltrim详解
    SQlite3 的简单用法。 调用本地时间
    RuntimeError at /host You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your fo
    D3.js 入门系列3
    js中const,var,let区别
    D3.js 入门系列2 — 选择元素和绑定数据
    D3.js 入门系列1
    SVG 教程03
  • 原文地址:https://www.cnblogs.com/zqq123/p/9249653.html
Copyright © 2011-2022 走看看