題意:問去掉最小多少的一段能使所有不同數字的個數為1。
題解:以去掉的長度為基準進行二分,因為ai能到達1e9,所以還要離散化,然後直接暴力查詢即可。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define lowbit(a) ((a)&-(a))
#define speed std::ios::sync_with_stdio(false),cin.tie(null),cout.tie(null)
using
namespace std;
typedef
long
long ll;
queue<
int> q;
priority_queue<
int> pq;
const
int maxn =
2005
;ll n,m;
ll ans=inf,cnt=0;
ll a[maxn]
,b[maxn]
;bool
check
(ll x)
for(k=i+x;k<=n;k++)if
(k==n+
1&&j==i)
return
true;}
return
false;}
intmain()
else
l=mid+1;
mid=
(l+r)/2
;}cout
}
看到了tourist的做法,感覺可以學習一下vector容器離散化的方法和去重的手法,下面是他的**和我的解釋
#include
using
namespace std;
intmain()
vector<
int> b = a;
sort
(b.begin()
, b.
end())
;//unique的返回值為不重複元素的最後乙個位置
b.resize
(unique
(b.begin()
, b.
end())
- b.
begin()
);//重新調整b容器的大小為不重複元素的終點到起點大小
//coutint) b.
size()
== n)
for(
int i =
0; i < n; i++
)//離散化
int ans =0;
vector<
int>
mark
(n,0
);v //二維陣列,每項初始化為零
for(
int i =
0; i < n; i++
) mark[a[n -
1- j]]=
1;//標記已出現過
++take;
//記錄取了幾個數字
} ans =
max(ans, i + take)
;//i是左邊取得數字,take是右邊取得數字
for(
int j =
0; j < take; j++)if
(mark[a[i]])
mark[a[i]]=
1;//記錄這個數字已出現過
} cout << n - ans <<
'\n'
;return0;
}
離散化 unique() 二分查詢
離散化 離散化,把無限空間中有限的個體對映到有限的空間中去,以此提高演算法的時空效率。通俗的說,離散化是在不改變資料相對大小的條件下,對資料進行相應的縮小。例如 原資料 1,999,100000,15 處理後 1,3,4,2 原資料 處理後 離散化是程式設計中乙個常用的技巧,它可以有效的降低時間複雜...
BZOJ4919 大根堆 線段樹合併 二分 離散化
題目鏈結 題意 給你一棵樹,每個點有點權,問你最多能選出多少個點,使得所有選出的點中子節點的權值都比父節點小 嚴格小於 點數2e5,權值1e9 題解 首先的乙個暴力是用乙個樹形dp,dp x i dp x i dp x i 表示點x xx為根的子樹內,最大權值是i ii時子樹內最多選的點數。我們不難...
離散化 去重 二分查詢
離散化是程式設計中乙個常用的技巧,它可以有效的降低時間複雜度。其基本思想就是在眾多可能的情況中,只考慮需要用的值。離散化可以改進乙個低效的演算法,甚至實現根本不可能實現的演算法。要掌握這個思想,必須從大量的題目中理解此方法的特點。例如,在建造線段樹空間不夠的情況下,可以考慮離散化。1 排序 2 去重...