【NOIP2015模拟11.5】Lucas的数列
Description
Input
Output
Sample Input
5 5
1 2
2 3
3 4
4 5
5 6
1 2 4
1 3 0
1 5 3
1 5 2
5 5 0
Sample Output
1
empty
6
1
empty
Data Constraint
反思&题解
比赛思路: 模拟,可惜被精度卡掉了一分没拿
正解思路: 我们可以看到式子很恶心,所以精度问题会特别猥琐,所以我们不妨将式子化简得:
,所以其实K一直都是一个整数 (出题人你不善良) ,又因为问题没有强制在线,所以我们可以考虑离线的做法,我们将元素和询问分别按照w和z为关键字从小到大进行排序,那么对于每次询问只有它之前的元素有贡献,之后我们只需要一个支持单点修改和区间查询的结构就行了,类似线段树和树状数组(我用的是线段树)
反思: 突然又发现自己线段树掌握的不怎么样,这是个很万能的东西,一定要将其练习得了如指掌
CODE
#include<bits/stdc++.h>
using namespace std;
struct arr
{
long long w,pos,num;
}a[400005];
struct huiyi
{
long long x,y,z,num1;
}b[400005];
bool cmp1(arr x,arr y)
{
return x.w<y.w;
}
bool cmp2(huiyi x,huiyi y)
{
return x.z<y.z;
}
long long tree[1500005],treenum[1500005],treesqr[1500005],n,q,ans[400005],t1,t2,t3;
void change(long long now,long long l,long long r,long long p,long long k)
{
if (l>p || r<p) return;
if (l==r && l==p)
{
tree[now]=1;
treenum[now]=k;
treesqr[now]=k*k;
}
else
{
long long mid=l+r>>1;
change(now<<1,l,mid,p,k);
change(now<<1|1,mid+1,r,p,k);
tree[now]=tree[now<<1]+tree[now<<1|1];
treenum[now]=treenum[now<<1]+treenum[now<<1|1];
treesqr[now]=treesqr[now<<1]+treesqr[now<<1|1];
}
}
void find(long long now,long long l,long long r,long long x,long long y)
{
if (l>y || r<x) return;
if (tree[now]==0) return;
if (l>=x && r<=y)
{
t1+=tree[now];
t2+=treenum[now];
t3+=treesqr[now];
}
else
{
long long mid=l+r>>1;
find(now<<1,l,mid,x,y);
find(now<<1|1,mid+1,r,x,y);
}
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%lld%lld",&n,&q);
long long i;
for (i=1;i<=n;i++)
{
scanf("%lld%lld",&a[i].w,&a[i].pos);
a[i].num=i;
}
for (i=1;i<=q;i++)
{
scanf("%lld%lld%lld",&b[i].x,&b[i].y,&b[i].z);
b[i].num1=i;
}
sort(a+1,a+1+n,cmp1);
sort(b+1,b+1+q,cmp2);
long long j=1;
for (i=1;i<=q;i++)
{
while (a[j].w<=b[i].z && j<=n)
{
change(1,1,n,a[j].num,a[j].pos);
j++;
}
t1=0;
t2=0;
t3=0;
find(1,1,n,b[i].x,b[i].y);
if (t1==0) ans[b[i].num1]=-1;
else ans[b[i].num1]=t1*t3-t2*t2;
}
for (i=1;i<=q;i++)
{
if (ans[i]==-1) printf("empty\n");
else printf("%lld\n",ans[i]);
}
return 0;
}