hdu6070
来源:互联网 发布:微信轰天雷炸群软件 编辑:程序博客网 时间:2024/06/02 06:06
多校第四场1004
Dirt Ratio
这个题意提炼出来就是让我们求一个序列中有区间中的不同数字和该区间长度的比值的最小值。
这个题目十分巧妙,因为之前刚刚写过codeforces上的一个类似题目,详见这里 : Codeforces Round #426 (Div. 2) D. The Bakery
当时做多校的时候有往这个方面去想但是又不知道怎么去做,看了题解后才有总结。
首先我们知道类似这种求不同颜色的题目,我们有一个方法就是维护一个S[],每当枚举到一个i时,我们记录num[i]最近一次出现的位置p,[p+1 , i]这段里的S都+1。这时,S[j]里面存的是从j到当前枚举的i里面有多少个不同的数字。
所以我们可以利用这个性质把这道题往这个方向上去靠,当前我们计算到i时,实际上就是要求 Sj/(i-j+1)的一个最小值。但是到这里用一般的数据结构应该还是不太好求,然后我们再试着把i和j分开。假设我们知道这个最小值minx = Sj/(i-j+1) => minx*i = Sj + minx* ( j-1) ,分开之后就好求很多了,当前枚举到i的时候,在前面里面找是否能有满足条件的j即可。然后这个最小值我们可以通过二分来枚举。
#include<cmath>#include<algorithm>#include<cstring>#include<string>#include<set>#include<map>#include<time.h>#include<cstdio>#include<vector>#include<list>#include<stack>#include<queue>#include<iostream>#include<stdlib.h>using namespace std;#define LONG long longconst LONG INF=0x3f3f3f3f;const LONG MOD=1e9+ 7;const double PI=acos(-1.0);#define clrI(x) memset(x,-1,sizeof(x))#define clr0(x) memset(x,0,sizeof x)#define clr1(x) memset(x,INF,sizeof x)#define clr2(x) memset(x,-INF,sizeof x)#define EPS 1e-10#define lson l , mid , rt<< 1#define rson mid + 1 ,r , (rt<<1)+1#define root 1, n , 1int take[61000] ;int a[65000] ;double tree[62000*4] ;double lazy[62000<<2];void Push_up(int rt){ tree[rt] = min(tree[rt<<1] , tree[rt<<1|1] ) ;}void Push_Down(int rt ){ lazy[rt<<1] += lazy[rt] ;tree[rt<<1|1] += lazy[rt ] ; tree[rt<<1] += lazy[rt] ;lazy[rt<<1|1] += lazy[rt] ; lazy[rt] = 0 ;}void Update(int L ,int R ,int l , int r , int rt ,double x){ if(L <= l && r<= R) { tree[rt] += x;lazy[rt] += x;return ; } Push_Down(rt) ;int mid = (l + r) /2 ; if(L <= mid)Update(L,R,lson ,x ) ; if(R > mid )Update(L ,R ,rson , x) ; Push_up(rt) ;}double Min(double a ,double b){ return a< b?a:b ;}double Que(int L ,int R , int l, int r , int rt ){ if(L <= l &&r <=R) return tree[rt] ; int mid = (l+r) / 2; Push_Down(rt) ; double res =1000000000.0; if(L <= mid)res =Min(res , Que(L , R,lson ) ) ; if(R > mid) res = Min(res , Que(L ,R ,rson ) ) ; return res ; }int main(){ int T ; int n ; cin >> T ; while(T --) { cin >> n ; for(int i =1; i<= n ; ++i) scanf("%d",&a[i] ) ; double l = 0 , r = 1.000 ; double mid ; for(;fabs(r -l ) >= 0.0001; ) { mid = ( l + r ) / 2; clr0(take) ; for(int i = 1; i<= n * 4 ; ++ i)tree[i] = 0,lazy[i] = 0 ; int judge = 0 ; for(int i = 1;i <= n ; ++ i) { int t ; if(take[a[i]] == 0) take[a[i]] = i , t = 0; else t = take[a[i]] , take[a[i] ] = i ; Update(i , i ,root , (double) (i-1) * mid ) ; Update(t+1 , i , root ,1.0) ; double res = Que(1,i,root) ; if(res <= (double)i*mid ) { judge = 1;break ; } } if(judge)r = mid ; else l = mid ; } printf("%.6lf\n",mid) ; }}
阅读全文
1 0
- hdu6070
- hdu6070 Dirt Ratio
- hdu6070 二分+线段树
- HDU6070 二分 线段树
- HDU6070-Dirt Ratio
- hdu6070 线段树+二分
- hdu6070 Dirt Ratio
- [HDU6070] Dirt Ratio
- HDU6070-Dirt Ratio
- HDU6070(线段树)
- 2017第四次多校联合hdu6070
- HDU6070 Counting Divisors(数论)
- HDU6070(分数规划+线段树)
- HDU6070(二分+线段树区间更新)
- [hdu6070] 2017hdu多校第四场
- HDU6070 [2017duoxiaolianhe4] Dirt Ratio xianduanshu + erfen
- HDU6070 Dirt Ratio(线段树+二分)
- hdu6070 Dirt Ratio(二分+线段树)
- 操作系统的页式管理
- 要素内部几何空间查询
- 【NOI2015模拟8.17】最短路(shortest)
- #HDU 1159 Common Subsequence
- JAVA-IO(3)操作简介
- hdu6070
- HDU 4609 3-idiots
- JS基础--常用对象
- Java8新时间与日期API—本地时间与时间戳
- 最长递增子序列
- windows 无法连接xxxxx (无法连接无线路由器)
- 学习笔记--操作系统的知识点的概括(思维导图形式)
- 监听者模式示例
- 备忘录