您的位置:首页 > 其它

[线段树 期望] BZOJ 2752: [HAOI2012]高速公路(road)

2016-04-27 19:42 417 查看
分母很显然 分子的话 展开后发现只要维护vi,vi*i, vi*i*i的和就好了

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;

inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}

inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

inline void read(char &x)
{
for (x=nc();x!='Q' && x!='C';x=nc());
}

const int N=100005;

ll Gcd(ll a,ll b){
if (a<b) return Gcd(b,a);
return b?Gcd(b,a%b):a;
}

inline ll sum(ll l,ll r) {
return (l+r)*(r-l+1)/2;
}
inline ll _sum2(ll n){
return n*(n+1)*(2*n+1)/6;
}
inline ll sum2(ll l,ll r){
return _sum2(r)-_sum2(l-1);
}

struct SEGTREE{
struct node{
int l,r;
ll s0,s1,s2;
friend node operator + (const node &A,const node &B) {
if (!A.l) return B;
if (!B.l) return A;
node ret;
ret.l=A.l; ret.r=B.r;
ret.s0=A.s0+B.s0; ret.s1=A.s1+B.s1; ret.s2=A.s2+B.s2;
return ret;
}
}T[N*4];
int M,TH;
ll H[N*4];
void Build(int n){
for (M=1,TH=0;M<n+2;M<<=1,TH++);
for (int i=1;i<=n;i++)
{
T[M+i].l=T[M+i].r=i;
}
for (int i=M-1;i;i--)
T[i]=T[i<<1]+T[i<<1|1];
}
void update(int rt,ll x){
int l=T[rt].l,r=T[rt].r;
H[rt]+=x;
T[rt].s0+=(r-l+1)*x;
T[rt].s1+=sum(l,r)*x;
T[rt].s2+=sum2(l,r)*x;
}
void Pushdown(int rt){
int p;
for (int i=TH;i;i--)
if (H[p=rt>>i])
{
update(p<<1,H[p]); update(p<<1|1,H[p]);
H[p]=0;
}
}
void add(int s,int t,ll r){
for (Pushdown(s+=M-1),Pushdown(t+=M+1);s^t^1;)
{
if (~s&1) update(s^1,r);
if ( t&1) update(t^1,r);
T[s>>=1]=T[s<<1]+T[s<<1|1];
T[t>>=1]=T[t<<1]+T[t<<1|1];
}
while (s>>=1)
T[s]=T[s<<1]+T[s<<1|1];
}
node query(int s,int t){
node lret,rret; lret.l=rret.l=0;
for (Pushdown(s+=M-1),Pushdown(t+=M+1);s^t^1;s>>=1,t>>=1)
{
if (~s&1) lret=lret+T[s^1];
if ( t&1) rret=T[t^1]+rret;
}
return lret+rret;
}
}Seg;

int n;
ll iP,iQ,D;

int main()
{
int Q,l,r,ix; char order;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(Q); Seg.Build(n-1);
while (Q--)
{
read(order); read(l); read(r);
if (order=='C')
{
read(ix);
Seg.add(l,r-1,ix);
}
else
{
SEGTREE::node ret=Seg.query(l,r-1);
iP=-ret.s2+(ll)(l+r-1)*ret.s1-(ll)(l-1)*r*ret.s0;
iQ=(ll)(r-l+1)*(r-l)/2;
D=Gcd(iQ,iP);
iP/=D; iQ/=D;
printf("%lld/%lld\n",iP,iQ);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: