제출 #850660

#제출 시각아이디문제언어결과실행 시간메모리
850660Dextar송신탑 (IOI22_towers)C++17
27 / 100
4077 ms28676 KiB
#include <cstdio>
#ifdef DEBUG
    #define D(X) X
#else
    #define D(X)
#endif
#include <bits/stdc++.h>
#define F first
#define S second
#define ll long long
#define pi 3.14159265359
#define pub push_back
#define pob pop_back
#define pari pair<int,int>
#define parli pair<long, long>

using namespace std;

const int INF = 1000 * 1000 * 1000;
const ll INF2 = 1LL * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
const int mod = 1000 * 1000 * 1000 + 7;

bool comp(vector<ll>& v1, vector<ll>& v2)
{
    return v1[0] < v2[0];
}


struct seg {
      vector<int> tree;
      int sz;

      void build(int n) {
          sz = 1;
          while(sz<n) {
              sz *= 2;
          }
          tree.resize(2*sz + 1, 0);
      }

      void clean()
      {
          for(int i=0; i<tree.size(); i++) {
              tree[i] = 0;
          }
      }

      void recSet(int idx, int lx, int rx, int i, int val) {
           if(rx-lx==1) {
               tree[idx] = val;
               return;
           }
           int mid = (lx+rx)/2;
           if(i<mid) {
               recSet(2*idx+1, lx, mid, i, val);
           } else
           {
               recSet(2*idx+2, mid, rx, i, val);
           }
           tree[idx] = max(tree[2*idx+1], tree[2*idx+2]);
      }

      void setX(int i, int val) {
          recSet(0, 0, sz, i, val);
      }

      int rec_range(int idx, int lx, int rx, int l, int r) {
          if(lx>=l&&rx<=r) {
              return tree[idx];
          }
          if(rx<=l||lx>=r) return 0;
          int mid = (lx+rx)/2;
          int left = rec_range(2*idx+1, lx, mid, l, r);
          int right = rec_range(2*idx+2, mid, rx, l, r);
          return max(left, right);
      }

      int range(int l, int r) {
          return rec_range(0, 0, sz, l, r);
      }
};


vector<int> dp;
seg mint, maxt;
map<int, int> ord;
vector<int> h;
int res = 0;
int center = -1;


void init2(int l, int r, int d)
{
    int n = h.size();
    res = 0;
    for(int i=0; i<=n; i++) {
        dp[i] = 0;
    }
    vector<int> used(n+1, 0);
    vector<int> nums;
    for(int i=l; i<=r; i++) {
        int f1 = 0, f2 = 0;
        nums.pub(h[i]);
        nums.pub(h[i]-d);
        nums.pub(h[i]+d);
        if(i>l) {
            if(h[i]>=h[i-1]) {
                f1 = 1;
            } else
            {
                f1 = 2;
            }
        }
        if(i<r) {
            if(h[i]>=h[i+1]) {
                f2 = 1;
            } else
            {
                f2 = 2;
            }
        }
        if(f1==0) {
            f1 = f2;
        }
        if(f2==0) {
            f2 = f1;
        }
        if(f1==f2) {
            used[i] = f1;
        }
    }
    sort(nums.begin(), nums.end());
    ord.clear();
    ord[nums[0]] = 0;
    int sz = nums.size();
    for(int i=1; i<sz; i++) {
        if(nums[i]>nums[i-1]) {
            ord[nums[i]] = ord[nums[i-1]] + 1;
        } else
        {
            ord[nums[i]] = ord[nums[i-1]];
        }
    }
    mint.clean();
    maxt.clean();
    mint.build(sz);
    maxt.build(sz);

    for(int i=r; i>=l; i--) {
        if(used[i]==0) {
            continue;
        }
        if(used[i]==1&&h[i]-d>0) {
            dp[i] = mint.range(0, ord[h[i]-d] + 1);
            maxt.setX(ord[h[i]], dp[i]);
        }
        if(used[i]==2) {
            dp[i] = 1 + maxt.range(ord[h[i]+d], sz);
            mint.setX(ord[h[i]], dp[i]);
        }
        res = max(res, dp[i]);
    }
}


void init(int n, vector<int> h2)
{
    h.resize(n);
    for(int i=0; i<n; i++) {
        h[i] = h2[i];
    }
    dp.resize(n+1);
    int idx = 1;
    while(idx<n&&h[idx]>=h[idx-1]) {
        idx++;
    }
    center = idx - 1;
    while(idx<n&&h[idx]<=h[idx-1]) {
        idx++;
    }
    if(idx!=n) {
        center = -1;
        init2(0, n - 1, 1);
    }
}

int max_towers(int l, int r, int d)
{
    if(center!=-1) {
        if(r<=center||l>=center) {
            return 1;
        }
        if(h[center]-h[l]>=d&&h[center]-h[r]>=d) {
            return 2;
        }
        return 1;
    }
    init2(l, r, d);
    if(l==0&&r==h.size()-1) {
        return res;
    }

    return res;
}

/*
4 0 3 20
0 1 2
1 2 3
18 1 19
*/

/*
int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    //D(freopen("input.txt","r",stdin);)
    //D(freopen("ouput.txt","w",stdout);)
    int t = 1;
    //cin >> t;
    loop:
    while(t--)
    {
        int n;
        cin >> n;
        vector<int> a(n);
        for(int i=0; i<n; i++) {
            cin >> a[i];
        }
        init(n, a);
        int res = max_towers(1, 5, 10);
        if(res==0) {
            res = 1;
        }
        cout << res;
    }
    return 0;
}
*/

컴파일 시 표준 에러 (stderr) 메시지

towers.cpp: In member function 'void seg::clean()':
towers.cpp:43:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   43 |           for(int i=0; i<tree.size(); i++) {
      |                        ~^~~~~~~~~~~~
towers.cpp: In function 'int max_towers(int, int, int)':
towers.cpp:199:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  199 |     if(l==0&&r==h.size()-1) {
      |              ~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...