$∑(l+r-1)*s[i]*i-s[i]*i^2+(r-l*r)*s[i]$,即$(l+r-1)*∑s[i]*i-∑s[i]*i^2+(r-l*r)*∑s[i]$,这样就可以用线段树维护s[i],s[i]*i,s[i]*i*i，通过普通的线段树就可以做出来了。

  1 #include<iostream>
2 #include<cstdio>
3 #define int long long
4 using namespace std;
5 struct tree
6 {
7     int l,r,sum1,sum2,sum3,sumi,sumi2,la;
8     #define l(x) tr[x].l
9     #define r(x) tr[x].r
10     #define sum1(x)  tr[x].sum1
11     #define sum2(x)  tr[x].sum2
12     #define sum3(x)  tr[x].sum3
13     #define sumi(x)  tr[x].sumi
14     #define sumi2(x) tr[x].sumi2
15     #define la(x)    tr[x].la
16 }tr[400010];
17 int gcd(int a,int b){return !b?a:gcd(b,a%b);}
18 int n,m;
19
20 void pushup(int x)
21 {
22     int ls=x*2,rs=x*2+1;
23     sum1(x)=sum1(ls)+sum1(rs);
24     sum2(x)=sum2(ls)+sum2(rs);
25     sum3(x)=sum3(ls)+sum3(rs);
26     sumi(x)=sumi(ls)+sumi(rs);
27     sumi2(x)=sumi2(ls)+sumi2(rs);
28 }
29 void build(int l,int r,int x)
30 {
31     l(x)=l,r(x)=r;
32     if(l==r)
33     {
34         sumi(x)=l,
35         sumi2(x)=l*l;
36         return;
37     }
38     int mid=(l+r)>>1;
39     build(l,mid,x*2);
40     build(mid+1,r,x*2+1);
41     pushup(x);
42 }
43 void down(int x)
44 {
45     if(l(x)==r(x))return;
46     if(!la(x))return;
47     int ls=x*2,rs=x*2+1;
48     la(ls)+=la(x),la(rs)+=la(x);
49     sum1(ls)+=(r(ls)-l(ls)+1)*la(x);
50     sum1(rs)+=(r(rs)-l(rs)+1)*la(x);
51     sum2(ls)+=sumi(ls)*la(x);
52     sum2(rs)+=sumi(rs)*la(x);
53     sum3(ls)+=sumi2(ls)*la(x);
54     sum3(rs)+=sumi2(rs)*la(x);
55     la(x)=0;
56     pushup(x);
57 }
58 void add(int l,int r,int x,int y)
59 {
60     if(l(x)==r(x))
61     {
62         sum1(x)+=y;
63         sum2(x)+=l(x)*y;
64         sum3(x)+=l(x)*l(x)*y;
65         return;
66     }
67     down(x);
68     if(l(x)>=l&&r(x)<=r)
69     {
70         la(x)+=y;
71         down(x);
72         return;
73     }
74     int mid=(l(x)+r(x))>>1;
77     pushup(x);
78 }
79 int ask1(int l,int r,int x)
80 {
81     down(x);
82     if(l(x)>=l&&r(x)<=r)
83         return sum1(x);
84     int ans=0,mid=(l(x)+r(x))>>1;
87     return ans;
88 }
89 int ask2(int l,int r,int x)
90 {
91     down(x);
92     if(l(x)>=l&&r(x)<=r)return sum2(x);
93     int ans=0,mid=(l(x)+r(x))>>1;
96     return ans;
97 }
98 int ask3(int l,int r,int x)
99 {
100     down(x);
101     if(l(x)>=l&&r(x)<=r)return sum3(x);
102     int ans=0,mid=(l(x)+r(x))>>1;
105     return ans;
106 }
107 signed main()
108 {
109     cin>>n>>m;n--;
110     build(1,n,1);
111     char op[3];int l,r,v;
112     for(int i=1;i<=m;i++)
113     {
114         cin>>op>>l>>r;
115         if(op[0]=='C')
116         {
117             cin>>v;
119         }
120         else
121         {
124             int len=r-l+1,tem;
125             tem=len*(len-1)/2;
126             int GCD=gcd(ans,tem);
127             if(ans==0)puts("0/1");
128             else printf("%lld/%lld\n",ans/GCD,tem/GCD);
129         }
130     }
131 }
View Code

posted @ 2019-07-25 06:22  Al_Ca  阅读(109)  评论(0编辑  收藏  举报