HDU - 6601 Keen On Everything But Triangle 数论+主席树

题目:hdu 6601

这个题其实是个很裸的主席树,关键是在复杂度分析。

首先,如果对于一个区间的所有值,我们想去选一个最大周长三角形该怎么选? 因为三角形的周长要最大,我们先把值从大到小排序。用Ki表示第 i 大的边,选出K1,K2,K3,如果K1<K2+K3的话,就能构成三角形且周长最大(K1+K2<K3,K1+K3<K2 必然成立)  如果不能构成三角形,我们思考一下 K1>=K2+K3,如果我们不选K3的话 因为Ki(i>=4) 肯定小于K2,K3 所以Ki和K1,K2必然不能构成三角形,因此我们只能舍弃K1,然后继续选K2,K3,K4构成三角形 这可以O(n) 完成 加上排序的复杂度 整个过程是 nlogn的  但是有q个询问 nqlogn的复杂度必然不行

显然按上述方法 我们找到一个成立的条件就会退出循环不在继续 我们想一下不能成立的极限条件是什么  

对于每三个相邻的项(排序后)满足: K_i=K_i_+_1+K_i_+_1

也就是斐波拉契数列:1 1 2 3 5 8 13.........         这样的话对于值域为1e9的斐波拉契数列  最多只有44项 也就是说 最多进行44次就能找到答案 

那么就有很明显的思路了 对于区间l到r 主席树暴力得到第K大,K-1大,K-2大,再按上述讨论的方法就行了

复杂度接近44*q*logn

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int c[N*30],lson[N*30],rson[N*30],T[N],t[N],a[N];
int n,m,q,tot;
typedef long long ll;
int Hash(int x){
	return lower_bound(t+1,t+1+m,x)-t;
}
int update(int rt,int pos,int val){
	int newrt=++tot,temp=newrt;
	int l=1,r=m;
	c[newrt]=c[rt]+val;
	while(l<r){
		int mid = l+r>>1;
		if(pos<=mid){
			r=mid;
			lson[newrt]=++tot;rson[newrt]=rson[rt];
			newrt=lson[newrt];rt=lson[rt];
		}else{
			l=mid+1;
			rson[newrt]=++tot;lson[newrt]=lson[rt];
			newrt=rson[newrt];rt=rson[rt];
		}
		c[newrt]=c[rt]+val;
	}
	return temp;
}
int query(int l_rt,int r_rt,int k){
	int l=1,r=m;
	while(l<r){
		int mid = l+r>>1;
		if(c[lson[r_rt]]-c[lson[l_rt]]>=k){
			r=mid;
			r_rt=lson[r_rt];l_rt=lson[l_rt];
		}else{
			k-=c[lson[r_rt]]-c[lson[l_rt]];
			l=mid+1;
			r_rt=rson[r_rt];l_rt=rson[l_rt];
		}
	}
	return l;
}
int main(){
	while(~scanf("%d%d",&n,&q)){
		m=tot=0;
		for(int i = 1; i <= n; i++){
			scanf("%d",&a[i]);
			t[++m]=a[i];
		}
		sort(t+1,t+1+m);
		m=unique(t+1,t+1+m)-t-1;
		for(int i = 1; i <= n; i++) T[i]=update(T[i-1],Hash(a[i]),1);
		for(int i = 1; i <= q; i++){
			int l,r;
			scanf("%d%d",&l,&r);
			int len = (r-l+1);
			ll ans = -1;
			while(len>=3){
				ll x1,x2,x3;
				x1=1ll*t[query(T[l-1],T[r],len)];
				x2=1ll*t[query(T[l-1],T[r],len-1)];
				x3=1ll*t[query(T[l-1],T[r],len-2)];
				if(x1<x2+x3){
					ans=x1+x2+x3;
					break;
				}
				len--;
			}
			printf("%lld\n",ans);
		}
	}
	return 0;
} 
原创文章 85 获赞 103 访问量 2488

猜你喜欢

转载自blog.csdn.net/weixin_43824564/article/details/105804974