2019.01.28【NOIP提高组】模拟B组 JZOJ 4235 序列

版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/86682967

D e s c r i p t i o n Description

给出 n n 个数,从中选出三个可以构成三角形三边的数(尽量靠前),回答 m m 次询问(带单点修改!)

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


S o l u t i o n Solution

比较容易想到 O ( n 3 m ) O(n^3m) 的暴力三重循环,然后加上最优化剪枝,我们假象一下出题人会怎样卡你

因为你打的是暴力,所以你的修改自然是 O ( 1 ) O(1) 的,如果出题人想卡,他必然会卡你查询这一部分。

既然要卡查询,由于你找到一组最优解就退出了,所以他会让最优解尽量靠后。

可是如果尽量靠后,他数据最小也就是酱紫的:
1,1,2,3,5,8,13,21……
发现了吗?对!就是斐波那契数列
F 50 F_{50} 是显然大于 1 0 9 10^9 的,也就是说答案最多是在前五十个数中,既然如此,暴力自然就可以水过咯

思考:
m m 加强到 1 0 5 10^5 ,该怎么做呢?
回答:
插入排序, O ( n 2 ) O(n^2) 回答询问,也可以用 s e t set ,这样就是 l o g log


C o d e Code

#pragma GCC optimize(2)
#include<cstdio>
#include<cctype>
#include<algorithm>
#define r(i,a,b) for(register int i=a;i<=b;i++)
#define d(i,a,b) for(register int i=a;i>=b;i--)
using namespace std;int n,a[100001],m,opt,x,y;
bool ok=false;
inline char Getchar()
{
    static char buf[10000000],*p1=buf+10000000,*pend=buf+10000000;
    if(p1==pend)
    {
        p1=buf; pend=buf+fread(buf,1,10000000,stdin);
        if (pend==p1) return -1;
    }
    return *p1++;
}
inline long long read()
{
    char c;int d=1;long long f=0;
    while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
    while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
    return d*f;
}
signed main()
{
	n=read();
	for(register int i=1;i<=n;i++) a[i]=read();
	m=read();
	while(m--)
	{
		opt=read();
		if(opt==1) {x=read();y=read();a[x]=y;}
		else
		{
			ok=false;
			r(i,3,n)
			{
				if(ok) break;
				r(j,1,i-1)
				{
					if(ok) break;
			  		r(k,1,j-1)
			   		if(a[i]+a[j]>a[k]&&a[i]+a[k]>a[j]&&a[k]+a[j]>a[i])
					{
					   	if(a[i]<=a[j]) 
						{
							if(a[i]<=a[k]) 
							{
								if(a[j]<=a[k]) printf("%d %d %d\n",a[i],a[j],a[k]);
								else printf("%d %d %d\n",a[i],a[k],a[j]);
							}
							else printf("%d %d %d\n",a[k],a[i],a[j]);
						}
						else
						{
							if(a[i]>a[k])
							{
								if(a[j]>a[k]) printf("%d %d %d\n",a[k],a[j],a[i]);
								else printf("%d %d %d\n",a[j],a[k],a[i]);
							}
							else printf("%d %d %d\n",a[j],a[i],a[k]);
						}
						ok=true;
						break;
					}
				}
			}
			if(!ok) puts("-1 -1 -1");
		}
	}
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/86682967
今日推荐