洛谷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 }