JZOJ 4235. 序列

题目

Description

 Fiugou想要在一个长度为N的序列A中找到不同位置的三个数,以这三个数为三边长来构成一个三角形。但是它希望在满足条件下,这三个数的位置尽量靠前。具体地,设这三个数的为Ai,Aj,Ak(i<j<k), Fiugou希望k尽量小;当k相等时,满足j尽量小;当k,j均相等时,满足i尽量小。
但是这个序列中的数可能会发生变化。所以Fiugou给出了M个操作,形式如下:
1 x y:将Ax改为y
2:查询最优的合法解,从小到大给出这三个数(而不是位置)。
 

Input

第一行一个整数N,代表序列的长度。
第二行有N个整数,代表初始序列。
第三行一个整数M,代表操作的个数。
接下来M行操作,两种操作格式如上所述。

Output

 共M行,每行三个数,从小到大给出。如果不存在,输出-1 -1 -1。
 

Sample Input

6
7 1 3 4 5 1
3
2
1 3 5
2

Sample Output

3 5 7
4 5 7
 

Data Constraint

对于10%的数据, N<=10, M<=5
对于30%的数据, N<=100, M<=25
对于50%的数据, N<=1000, M<=1000
对于100%的数据, N<=100000, M<=1000
对于100%的数据, 0<=Ai<=10^9, 1<=x<=N, 0<=y<=10^9

 

 

分析

  •    首先,我们肯定知道如何用暴力的方法做

  •    O(n^3)   但是数据太水。。。能过

  •    正解:其实不能组成三角形的情况也就是一个feb数列
  •    我们可以得知feb 到了第五十位是很大的
  •    也就是说在这个数列中,如果一旦超过五十个后面将视为无效
  •    因为如果在前50个数中每个数都不一样 那么一定能组成一个最小的
  •    这道题主要是想卡-1-1-1的情况,所以如果我们超出50个数之后还有的话那么已经超出数据规模了

代码

 1 #include<iostream>
 2 using namespace std;
 3 int a[100001];
 4 int main ()
 5 {
 6     ios::sync_with_stdio(false);
 7     int n,m;
 8     cin>>n;
 9     for (int i=1;i<=n;i++)
10         cin>>a[i];
11     cin>>m;
12     bool flag=0;
13     for (int i=1,x,y,z,b=-1,c=-1,d=-1;i<=m;i++)
14     {
15         cin>>x;
16         if (x==2)
17         {
18             flag=1;
19             int bk=0;
20             for (int ii=3;ii<=min(n,50);ii++)
21             {
22                 if (bk==1)
23                    break;
24                 for (int j=1;j<=ii-1;j++)
25                 {
26                     if (bk==1)
27                       break;
28                     for (int k=1;k<=j-1;k++)
29                         if (a[ii]+a[j]>a[k]&&a[ii]+a[k]>a[j]&&a[j]+a[k]>a[ii])
30                         {
31                             b=min(a[ii],min(a[j],a[k]));
32                             if (b==a[ii])
33                             {
34                                 c=min(a[j],a[k]);
35                                 if (c==a[j])
36                                     d=a[k];
37                                 else
38                                     d=a[j];
39                             }
40                             if (b==a[j])
41                             {
42                                 c=min(a[ii],a[k]);
43                                 if (c==a[ii])
44                                     d=a[k];
45                                 else
46                                     d=a[ii];
47                             }
48                             if (b==a[k])
49                             {
50                                 c=min(a[ii],a[j]);
51                                 if (c==a[ii])
52                                     d=a[j];
53                                 else
54                                     d=a[ii];
55                             }
56                             bk=1;
57                             break;
58                         }
59                 }
60             }    
61             cout<<b<<" "<<c<<" "<<d<<endl;
62         }
63         else
64         {
65             flag=0;
66             cin>>y>>z;
67             a[y]=z;
68         }
69     }
70 }

 

为何要逼自己长大,去闯不该闯的荒唐
原文地址:https://www.cnblogs.com/zjzjzj/p/10331939.html