【题目】
1010 Just Skip The Problem
【题意】
给你一个未知数n,1到n内随机产生一个数x,每次可以选择一个数y跟x进行与运算,东家会告诉是否等于y,问多少次可以确定这个数
【解法】
答案其实就是n的阶乘
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e6+3;
const int N = 1e6+100;
ll a[N];
int main()
{
a[0]=1;
for(int i=1;i<=1e6+4;i++) a[i]=a[i-1]*i%mod;
int n;
while(~scanf("%d",&n)){
if(n<=1e6+3) printf("%lld\n",a[n]%mod);
else {
printf("%lld\n",0);
}
}
}
【题目】
1011 Keen On Everything But Triangle
【题意】
给出n个数,给m次查询,每查询,l,r区间,问区间内选三个值能组成三角形的最大周长是多少。
【题解】
维护区间内前K大,只需要枚举前46大左右就可以。先取第一大和第二大第三大,比较,若不能构成三角形,那么第二大,第三大,第四大在作比较.理由:若找前46个都不能找到三角形,那么前46个数至少符合Fibonacci数的递增方式,当达到n=46左右的Fibonacci数时就已经超出题目给的范围了。证毕。。。
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m,sum[40*N],ls[40*N],rs[40*N],rt[N],sz,k,cnt;
ll a[N],b[N];
void up(int pre,int &o,int l,int r,int pos)
{
o=++cnt;
ls[o]=ls[pre];
rs[o]=rs[pre];
sum[o]=sum[pre]+1;
if(l==r) return ;
int mid=l+r>>1;
if(pos<=mid)
{
up(ls[pre],ls[o],l,mid,pos);
}
else up(rs[pre],rs[o],mid+1,r,pos);
}
ll qu(int pre,int o,int l,int r)
{
if(l==r) return b[l];
int mid=l+r>>1;
int cmp=sum[rs[o]]-sum[rs[pre]];
//int cmp=sum[ls[o]]-sum[ls[pre]];
if(cmp>=k) return qu(rs[pre],rs[o],mid+1,r);
else
{
k-=cmp;
return qu(ls[pre],ls[o],l,mid);
}
}
void init()
{
cnt=0;
/*
memset(sum,0,sizeof(sum));
memset(ls,0,sizeof(ls));
memset(rs,0,sizeof(rs));
memset(rt,0,sizeof(rt));
*/
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
sz=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++)
{
int j=lower_bound(b+1,b+1+sz,a[i])-b;
up(rt[i-1],rt[i],1,sz,j);
}
while(m--)
{
int ql,qr;
scanf("%d%d",&ql,&qr);
if(qr-ql+1<3) printf("-1\n");
else{
ll val[5],cnt=0;
int tmk=0;k=0;
bool flag=0;
k=1;
tmk=1;
val[++cnt]=qu(rt[ql-1],rt[qr],1,sz);
k=2;
tmk=2;
val[++cnt]=qu(rt[ql-1],rt[qr],1,sz);
while(tmk<=46&&tmk<qr-ql+1)
{
++tmk;
k=tmk;
val[++cnt]=qu(rt[ql-1],rt[qr],1,sz);
/*puts("val");
for(int i=1;i<=3;++i) printf("%d ",val[i]);
puts("");*/
if(cnt==3)
{
if(val[1]<val[2]+val[3])
{
printf("%lld\n",val[1]+val[2]+val[3]);
flag=1;break;
}
val[1]=val[2];
val[2]=val[3];
--cnt;
}
}
if(!flag) printf("-1\n");
}
}
}
}