洛谷P2221 [HAOI2012]高速公路

线段树

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<vector>
  6 #define INF 0x7f7f7f7f
  7 #define MAXN 100005
  8 #define rint register int
  9 #define pb push_back
 10 #define pii pair<int,int>
 11 #define mp make_pair
 12 #define ft first
 13 #define sc second
 14 #define ll long long
 15 using namespace std;
 16 ll read(){
 17     ll x=0,f=1;char ch=getchar();
 18     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
 19     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 20     return x*f;
 21 }
 22 struct Node{
 23     int L,R;
 24     ll vl,sum;
 25     ll lv,rv;
 26     ll tag;
 27     Node(){
 28         L=R=0;
 29         vl=sum=lv=rv=tag=0LL;
 30     }
 31 }st[MAXN<<2];
 32 ll cnt[MAXN];
 33 void work(int k,ll v){
 34     int len=st[k].R-st[k].L+1;
 35     st[k].vl+=cnt[len]*v;
 36     st[k].sum+=len*v;
 37     st[k].lv+=(1+len)*len/2*v;
 38     st[k].rv+=(1+len)*len/2*v;
 39     st[k].tag+=v;
 40 }
 41 Node Merge(Node A,Node B){
 42     if(!A.L&&!A.R)return B;
 43     if(!B.L&&!B.R)return A;
 44     Node r;r.L=A.L,r.R=B.R;
 45     int len1=A.R-A.L+1,len2=B.R-B.L+1;
 46     r.sum=A.sum+B.sum;
 47     r.vl=A.vl+B.vl+len2*A.rv+len1*B.lv;
 48     r.lv=A.lv+len2*A.sum+B.lv;
 49     r.rv=B.rv+len1*B.sum+A.rv;
 50     return r;
 51 }
 52 void pushdown(int k){
 53     if(st[k].tag){
 54         work(k<<1,st[k].tag);
 55         work(k<<1|1,st[k].tag);
 56         st[k].tag=0;
 57     }
 58 }
 59 void build(int k,int L,int R){
 60     st[k].L=L,st[k].R=R;
 61     if(L==R){
 62         st[k].vl=0,st[k].sum=0;
 63         st[k].lv=0,st[k].rv=0;
 64         st[k].tag=0;
 65     }
 66     else{
 67         int mid=(L+R)>>1;
 68         build(k<<1,L,mid);
 69         build(k<<1|1,mid+1,R);
 70         st[k]=Merge(st[k<<1],st[k<<1|1]);
 71     }
 72 }
 73 Node query(int k,int a,int b){
 74     int L=st[k].L,R=st[k].R;
 75     if(a<=L&&R<=b){
 76         return st[k];
 77     }
 78     else{
 79         pushdown(k);
 80         Node r;
 81         int mid=(L+R)>>1;
 82         if(a<=mid)r=Merge(r,query(k<<1,a,b));
 83         if(b>mid)r=Merge(r,query(k<<1|1,a,b));
 84         return r;
 85     }
 86 }
 87 void add(int k,int a,int b,ll v){
 88     int L=st[k].L,R=st[k].R;
 89     if(a<=L&&R<=b){
 90         work(k,v);
 91     }
 92     else{
 93         pushdown(k);
 94         int mid=(L+R)>>1;
 95         if(a<=mid)add(k<<1,a,b,v);
 96         if(b>mid)add(k<<1|1,a,b,v);
 97         st[k]=Merge(st[k<<1],st[k<<1|1]);
 98     }
 99 }
100 int n,m;
101 ll s1[MAXN],s2[MAXN];
102 void init(){
103     n=read(),m=read();
104     for(rint i=1;i<=n;i++){
105         s1[i]=s1[i-1]+i;
106         s2[i]=s2[i-1]+1LL*i*i;
107     }
108     for(rint i=1;i<=n;i++){
109         cnt[i]=(i+1)*s1[i]-s2[i];
110     }
111     build(1,1,n);
112 }
113 ll gcd(ll a,ll b){return (!b?a:gcd(b,a%b));}
114 void solve(){
115     char s[5];
116     int x,y;ll v;
117     while(m--){
118         scanf("%s%d%d",s,&x,&y);
119         y--;
120         if('C'==s[0]){
121             scanf("%lld",&v);
122             add(1,x,y,v);
123         }
124         else{
125             Node r=query(1,x,y);
126             ll a=1LL*(y-x+2)*(y-x+1)/2;
127             ll b=r.vl;
128             ll c=gcd(a,b);
129             a/=c,b/=c;
130             printf("%lld/%lld\n",b,a);
131         }
132     }
133 }
134 int main()
135 {
136 //    freopen("data.in","r",stdin);
137     init();
138     solve();
139     return 0;
140 }

 

posted @ 2018-03-22 22:49  white_hat_hacker  阅读(184)  评论(0编辑  收藏  举报