Trade Guilds of Erathia
Time limit: 2.0 second
Memory limit: 64 MB
Memory limit: 64 MB
The continent of Antagarich was colonized slowly. Long ago its northern part was inhabited by the elves of Avlee. Later, the hot southern desert of Bracada was occupied by the white mages. At the same time, necromancers settled in Deyja, a land to the north of Bracada and to the south-west of Avlee. Although white and dark mages didn't really like each other, each group had some artifacts that the other group would be happy to buy. As a result, the trading relationship between Bracada and Deyja grew stronger, and soon the mages built a very busy trade route between these lands.
Erathia was founded later, and at first it was stretched along this route. At that time Erathia's economy was based solely on trading, so new trading guilds appeared all the time. Each of the guilds was present in a few cities which were consecutively situated along the route. Caravans of each guild travelled between all pairs of cities of that guild equally often.
The state's treasury was replenished by fees collected from all the caravans moving along the trade route. There was a fee for each route segment connecting two neighboring cities, and this fee could change over time. For example, the fee could be decreased in the areas of frequent goblin attacks, or increased in the areas with high traffic.
Loins, the royal treasurer, studies Erathia's economy and tries to predict the profit of trade guilds. He wants to know the amount of money paid in fees by each guild. He has a chronologically ordered list of documents that contains all the royal orders changing the fee and all the papers establishing new guilds. This data should be used to calculate the average fee paid by a caravan of a given trade guild.
Input
The first line contains the number n of cities in Erathia and the number m of documents collected by Loins (2 ≤ n ≤ 105; 1 ≤ m ≤ 105). The following m lines describe the documents of two possible types:
- “change a b d”: the fee for travelling along each route segment between cities a and bchanged by d gold coins (if d is positive, the fee increased; if d is negative, the fee decreased);
- “establish a b”: a new guild which is present in all cities between a and b was established.
All numbers are integers; 1 ≤ a < b ≤ n; −10 000 ≤ d ≤ 10 000. Cities are numbered in the order they are located along the route: from Bracada to Deyja. The fee for travelling along a segment was never larger than 10 000 gold coins, otherwise merchants would protest. Of course, the fee was always non-negative. Before the first royal order changing the fee, it is equal to zero for all route segments.
Output
After each document establishing the new guild, output in a single line the average amount of fee paid by a caravan of this guild. The absolute or relative error should not exceed 10−6.
Sample
input | output |
---|---|
4 5 |
1.00000000 |
分析:设询问区间为[l,r],第k条路编号为k+1;
则第k条路的贡献为(k-l)*(r-k+1)*cost[k];
展开后即[-k*k+(l+1+r)*k-l-l*r]*cost[k];
线段树单点维护好cost[k],k*cost[k],k*k*cost[k]即可;
注意爆int;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
const int maxn=1e5+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p;p=p*p;q>>=;}return f;}
int n,m,k;
char op[];
ll ans[];
ll gao(int p)
{
return (ll)p*(p+)*(*p+)/;
}
struct Node
{
ll sum,sum1,sum2,lazy;
} T[maxn<<]; void PushUp(int rt)
{
T[rt].sum = T[rt<<].sum + T[rt<<|].sum;
T[rt].sum1 = T[rt<<].sum1 + T[rt<<|].sum1;
T[rt].sum2 = T[rt<<].sum2 + T[rt<<|].sum2;
} void PushDown(int L, int R, int rt)
{
int mid = (L + R) >> ;
ll t = T[rt].lazy; T[rt<<].sum += t * (mid - L + );
T[rt<<|].sum += t * (R - mid); T[rt<<].sum1 += t * (mid - L + )*(mid + L)/;
T[rt<<|].sum1 += t * (R - mid)*(R + mid +)/; T[rt<<].sum2 += t * (gao(mid)-gao(L-));
T[rt<<|].sum2 += t * (gao(R)-gao(mid)); T[rt<<].lazy += t;
T[rt<<|].lazy += t;
T[rt].lazy = ;
} void Update(int l, int r, ll v, int L, int R, int rt)
{
if(l==L && r==R)
{
T[rt].lazy += v;
T[rt].sum += v * (R - L + );
T[rt].sum1 += v * (R - L + )*(R + L)/;
T[rt].sum2 += v * (gao(R)-gao(L-));
return ;
}
int mid = (L + R) >> ;
if(T[rt].lazy) PushDown(L, R, rt);
if(r <= mid) Update(l, r, v, Lson);
else if(l > mid) Update(l, r, v, Rson);
else
{
Update(l, mid, v, Lson);
Update(mid+, r, v, Rson);
}
PushUp(rt);
} void Query(int l, int r, int L, int R, int rt)
{
if(l==L && r== R)
{
ans[]+=T[rt].sum;
ans[]+=T[rt].sum1;
ans[]+=T[rt].sum2;
return;
}
int mid = (L + R) >> ;
if(T[rt].lazy) PushDown(L, R, rt);
if(r <= mid) Query(l, r, Lson);
else if(l > mid) Query(l, r, Rson);
else Query(l, mid, Lson) , Query(mid + , r, Rson);
}
int main()
{
int i,j;
scanf("%d%d",&n,&m);
while(m--)
{
int a,b,c;
scanf("%s",op);
if(op[]=='c')
{
scanf("%d%d%d",&a,&b,&c);
Update(a+,b,(ll)c,,n,);
}
else
{
scanf("%d%d",&a,&b);
ans[]=ans[]=ans[]=;
Query(a+,b,,n,);
printf("%.10f\n",(double)(-ans[]+(a+b+)*ans[]-(a+(ll)a*b)*ans[])/(b-a)/(b-a+)*);
}
}
//system("Pause");
return ;
}