Lucas的数列
description
solution
看到分母,先推式子,不难推出,\(K=m\cdot \sum_{i=1}^{m}x_{i}^{2} +(\sum_{i=1}^{m} x_{i})^{2}\),明显满足区间减法,于是可以考虑直接用主席树维护,但空间不允许我们这么做.
由于本题可以离线计算,统一输出答案,所以我们不妨将元素和查询一同输入,然后将其按\(w\)或\(z\)从小到大排序,若相同,元素在查询前头.所以我们可以使用树状数组或线段树进行维护.
code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define R register
#define next MabLcdG
#define mod 1
#define Mod(x) ((x%mod+mod)%mod)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writesp(ll x);
inline void writeln(ll x);
ll n,m;
const ll maxn=400001;
struct node{
ll w;
ll l,r;
ll id;
bool operator <(node X)const{return w==X.w?id<X.id:w<X.w;}
}t[maxn<<1];
ll dat[maxn*3+(maxn>>1)],dat1[maxn*3+(maxn>>1)],dat2[maxn*3+(maxn>>1)];
ll tot;
inline void update(ll p,ll l,ll r,ll u){
if(l==r){
dat[p]++;dat1[p]+=t[u].l*t[u].l;dat2[p]+=t[u].l;
return;
}
ll mid=l+r>>1;
if(t[u].r<=mid) update(p<<1,l,mid,u);
else update(p<<1|1,mid+1,r,u);
dat[p]=dat[p<<1]+dat[p<<1|1];
dat1[p]=dat1[p<<1]+dat1[p<<1|1];
dat2[p]=dat2[p<<1]+dat2[p<<1|1];
}
ll ans1,ans2,ans3;
ll ans[maxn];
inline void query(ll p,ll l,ll r,ll u,ll v){
if(u<=l&&r<=v){
ans1+=dat[p];ans2+=dat1[p];ans3+=dat2[p];
return;
}
ll mid=l+r>>1;
if(u<=mid) query(p<<1,l,mid,u,v);
if(v>mid) query(p<<1|1,mid+1,r,u,v);
}
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
// writeln((sizeof t+sizeof dat+sizeof dat1+sizeof dat2+sizeof ans)>>20);
n=read();m=read();
for(R ll i=1;i<=n;i++){
t[++tot].w=read();t[tot].l=read();t[tot].r=i;
}
for(R ll i=1;i<=m;i++){
t[++tot].l=read();t[tot].r=read();t[tot].id=i;t[tot].w=read();
}
sort(t+1,t+tot+1);
for(R ll i=1;i<=tot;i++){
// writesp(t[i].w);writesp(t[i].l);writeln(t[i].r);
if(!t[i].id){
update(1,1,n,i);
}
else{
ans1=ans2=ans3=0;
query(1,1,n,t[i].l,t[i].r);
// writeln(ans1*ans2-ans3*ans3);
ans[t[i].id]=ans1*ans2-ans3*ans3;
if(!ans1) ans[t[i].id]=-1;
}
}
for(R ll i=1;i<=m;i++){
if(ans[i]==-1) puts("empty");
else writeln(ans[i]);
}
}
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
inline void writesp(ll x){write(x);putchar(' ');}
inline void writeln(ll x){write(x);putchar('\n');}