题解的思路在讨论版都有,和出题人的思路是一样的,这里我就发一份用线段树过的题解(899ms)。
同时也希望大家多逛逛我的博客(https://www.cnblogs.com/Mmasker/ )。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> PII; #define ls l,mid,rt<<1 #define rs mid+1,r,rt<<1|1 const int MAXN = 4e6+10; const int T = 3e5+10; const double EPS = 1e-12; const ll mod = 1e9+7; int Q; ll a[MAXN<<2][6]; inline void Update(int l,int r,int rt,int p,int v,int t,int m,int x){ if(l==r&&l==p){ if(x==0)a[rt][x]=(a[rt][x]+1ll*m*v*v)%mod; else if(x==1)a[rt][x]=(a[rt][x]+2ll*m*v*10)%mod; else if(x==2)a[rt][x]=(a[rt][x]+2ll*m*v*10*t)%mod; else if(x==3)a[rt][x]=(a[rt][x]+1ll*m*100)%mod; else if(x==4)a[rt][x]=(a[rt][x]+2ll*t*m*100)%mod; else a[rt][x]=(a[rt][x]+1ll*m*t*t*100)%mod; return ; } int mid=(l+r)/2; if(p<=mid)Update(ls,p,v,t,m,x); else Update(rs,p,v,t,m,x); a[rt][x]=(a[rt<<1][x]+a[rt<<1|1][x])%mod; } inline ll Query(int l,int r,int rt,int p,int x){ if(p>=r)return a[rt][x]; int mid=(l+r)/2; ll ans=0; if(p>mid)ans=(ans+Query(rs,p,x))%mod; ans=(ans+Query(ls,p,x))%mod; return ans; } int main() { scanf("%d",&Q); while(Q--){ int op; scanf("%d",&op); if(op==1){ int v,t,m; scanf("%d %d %d",&v,&t,&m); int V=v+10*(T-t); Update(1,4e6,1,V,v,t,m,0); Update(1,4e6,1,V,v,t,m,1); Update(1,4e6,1,V,v,t,m,2); Update(1,4e6,1,V,v,t,m,3); Update(1,4e6,1,V,v,t,m,4); Update(1,4e6,1,V,v,t,m,5); } else{ int v,t; scanf("%d %d",&v,&t); int V=v+10*(T-t); ll ans=0; ans=(ans+Query(1,4e6,1,V,0))%mod; ans=(ans+Query(1,4e6,1,V,1)*t)%mod; ans=(ans-Query(1,4e6,1,V,2))%mod; ans=(ans+Query(1,4e6,1,V,3)*t%mod*t%mod)%mod; ans=(ans-Query(1,4e6,1,V,4)*t)%mod; ans=(ans+Query(1,4e6,1,V,5))%mod; printf("%lld\n",(ans+mod)%mod); } } }