ACM的探索之Keen On Evrything But Triangle(我觉得可以很接近啦!!)

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,q,l,r;
	while(cin>>n>>q)
	{
		vector<int> a(n);
		for(int i=0;i<n;i++) cin>>a[i];
		while(q--)
		{
			cin>>l>>r;
			vector<int> b(r-l+1);
			for(int i=0;i<r-l+1;i++) b[i]=a[i+l-1];
			sort(b.begin(),b.end());
			int len=r-l+1;
			int x=b[len-1];
			int y=b[len-2];
			int z=b[len-3];
			cout<<x+y+z<<endl;
		}
	}
	return 0;
}  //好接近了,但是因为超时被卡住了!

  接下来是题目喽:

援引自https://blog.csdn.net/xizi_ghq                  https://blog.csdn.net/xizi_ghq/article/details/97136436

题意:给出一个数列,询问任意区间,区间内所组成的最大的三角形周长是多少?

首先要明白斐波那契的一个性质,刚刚好不能够组成三角形,然后根据这个性质,1e9的范围内,如果一直不能构成三角形,最大只有47个数(47层)。这样我们从每个区间取出最大的47个数,然后来判断这47个数满足题意的三角形周长就可以了。

很明显主席树查询第k大模板

大佬的代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int M=1e5+50; 
 4 int n,q,d[M],b[M],root[M],cnt;
 5 struct Node{int l,r,sum;}t[40*M];
 6 void build(int &rot,int l,int r){
 7     rot=++cnt;
 8     t[rot].sum=0;
 9     if(l==r)return ;
10     int mid=(l+r)>>1;
11     build(t[rot].l,l,mid);
12     build(t[rot].r,mid+1,r);
13 } 
14 void update(int &rot,int l,int r,int last ,int v){
15     rot=++cnt;
16     t[rot].l=t[last].l;
17     t[rot].r=t[last].r;
18     t[rot].sum=t[last].sum+1;
19     if(l==r)return ;
20     int mid=(l+r)>>1;
21     if(v<=mid)update(t[rot].l,l,mid,t[last].l,v);
22     if(mid<v)update(t[rot].r,mid+1,r,t[last].r,v);
23 }
24 bool judge(int x,int y,int z){
25     char xx[3];
26     xx[0]=x;
27     xx[1]=y;
28     xx[2]=z;
29     sort(xx,xx+3);
30     if(xx[0]+xx[1]<=xx[2])return false;
31     return true;
32 }
33 int ask(int pre,int now,int l,int r,int k){
34     if(l==r)return l;
35     int mid=(l+r)>>1,num=t[t[now].r].sum-t[t[pre].r].sum;
36     if(k<=num)return ask(t[pre].r,t[now].r,mid+1,r,k);
37     return ask(t[pre].l,t[now].l,l,mid,k-num);
38 }
39 int main(){
40     while(scanf("%d%d",&n,&q)!=EOF){ 
41         cnt=0;
42         
43         for(int i=1;i<=n;i++){
44             scanf("%d",d+i);
45             b[i]=d[i];
46         }
47         sort(b+1,b+n+1);        
48         int sz=unique(b+1,b+n+1)-(b+1);    
49         for(int i=1;i<=n;i++)d[i]=lower_bound(b+1,b+sz+1,d[i])-b;
50         build(root[0],1,sz); 
51         for(int i=1;i<=n;i++)update(root[i],1,sz,root[i-1],d[i]); //通过上个树,来更新这个树 
52         long long  res[55]; 
53         for(int x,y,k,mx,f,i=1;i<=q;i++){
54             scanf("%d%d",&x,&y);
55             mx=min(50,y-x+1);
56             if(mx<3){
57                 printf("-1\n");
58                 continue;
59             }
60             for(int j=1;j<=mx;j++) res[j] = b[ask(root[x-1],root[y],1,sz,j)]; //找到第k大的数字 
61             f=0;
62             for(int j=3;j<=mx;j++){
63                 if(res[j]+res[j-1]>res[j-2]){
64                     f=1;
65                     printf("%lld\n",res[j]+res[j-1]+res[j-2]);
66                     break;
67                 }
68             }
69             if(!f)printf("-1\n");
70         }
71     }            
72     return 0;
73 }

tql !!!!!!

posted @ 2019-07-24 16:06  龙龙666666  阅读(169)  评论(0编辑  收藏  举报