hdu 4037 Development Value(线段树维护数学公式)

Development Value

Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)

Total Submission(s): 609    Accepted Submission(s): 118

Problem Description

StarCraft 2 (SC2) is a famous game. More and more people fall in love with this game.

As a crazy fan of SC2, Ahua (flower fairy) play it day and night. Recently, he found that the most important part of being a top player of SC2 is economic development, which means you should get as much mine as possible by training SCVs (space construction
vehicle) to collect mine. Train a SCV at ith second costs Ci units of mine. After training, this SCV can collect Di units of mine each second. Training a SCV needs one second of time.

Based on that, he composes a formula to evaluate the development in a time span from xth second to yth second. Assume at xth second, Ahua has no SCV and mine. He trains one SCV at each second during xth second and yth second (the mount of mine can be negative,
so that he always can train SCV). Each SCV will collect some amount of mines for Ahua in each second after it was trained. At ith second Ahua has Mi units of mine in total. The development value is defined as sum(Mi) (x ≤ i ≤ y). Now he asks you to help him
calculate the development value. To make it more interesting, Ahua can apply following operations:

Cost x y z: the cost of training a SCV between xth second to yth second will increase by z units of mine. i.e. Ci for x ≤ i ≤ y will increase by z.

Collect x y z: each SCV trained between xth second and yth second can collect z more mines every second after it has been trained. i.e. Di for x ≤ i ≤ y will increase by z.

Query x y: output the development value between xth second and yth second.

Input

First line of the input is a single integer T (T ≤ 10), indicates there are T test cases.

For each test case, the first line is an integer N (1 ≤ N ≤ 100000), means the maximum time you should deal with.

Following N lines, each contain two integers Ci and Di (0 ≤ Ci, Di ≤ 100000), the cost and collect speed of SCV training in ith second initially as described above.

The next line is an integer Q (1 ≤ Q ≤ 10000), the number of operations you should deal with. Then Q lines followed, each line will be “Cost x y z”, "Collect x y z” or “Query x y”.

1 ≤ x ≤ y ≤ N, 0 ≤ z ≤ 100000

Output

For each test case, first output “Case k: “ in a single line, k is the number of the test case, from 1 to T. Then for each "Q x y", you should output a single line contains the answer mod 20110911.

Sample Input

1
5
1 3
2 3
3 1
2 2
3 3
5
Query 1 3
Cost 2 2 1
Query 1 3
Collect 1 1 5
Query 1 3

Sample Output

Case 1:
2
0
15

Source

The 36th ACM/ICPC Asia Regional Chengdu Site —— Online
Contest

Recommend

lcy   |   We have carefully selected several similar problems for you:  4038 4036 4039 4032 4033

题意:

有一个游戏。里面要造矿兵。在第i秒造矿兵需要花费c[i]。然后之后的时间每秒该矿兵都会采d[i]的矿。然后询问。从x秒到y秒。每秒造一个矿兵.(在x秒的时候矿兵和矿都为0.但是矿可以为负数)。然后定义了一个mi。表示第i秒时的总矿数。然后要你输出.Σmi(x<=i<=y)。

思路:

先推公式。

1,考虑花费

时刻j  从x时刻到j时刻造农民的总花费

x  C(x)

x+1  C(x)+C(x+1)

x+2  C(x)+C(x+1)+C(x+2)

......

y  C(x)+C(x+1)+...+C(y)

对第二栏求和,每一列是C(i)*(y-i+1),再对这个从x到y求和,得sigma(C(i)*(y+1-i))

分成两项(y+1)*sigma(C(i))-sigma(C(i)*i)

2,考虑采矿

对于i时刻被造出的农民,到j时刻总共采的矿数是D(i)*(j-i),对这个从x到j求和就是j时刻之前造的农民到j时刻为止总共采的矿数,即sigma(D(i)*(j-i))(对i从x到j求和),再对j从x到y求和就是答案。但是这个形式的求和式不适合用线段树维护,做些变形:

时刻j sigma(D(i)*(j-i))

x   D(x)*0

x+1  D(x)*1+D(x+1)*0

x+2  D(x)*2+D(x+1)*1+D(x+2)*0

......

y  D(x)*(y-x)+D(x+1)*(y-x-1)+......+D(y-1)*1+D(y)*0

对第二栏求和,每列是D(i)*(y-i)*(y-i+1)/2,再对这个从x到y求和,sigma(D(i)*(y-i)*(y-i+1)/2).

把和式拆成几项方便维护:1/2*( y*(y+1)sigma(D(i)) - (2*y+1)sigma(D(i)*i) + sigma(D(i)*i^2))

然后最后的答案就是采矿-花费。

然后只需要用一颗线段树来维护。

sigma(ci),sigma(i*ci),sigma(di),sigma(i*di),sigma(i*i*di).

然后按一般的更新查询就完了。

对于除二取模的问题。

(1)模数乘2,所有中间过程直接取模,最后得数/2

(2)直接取模,最后答案是ret,如果ret是偶数,答案是ret/2,如果是奇数,答案是(ret + mod) / 2

详细见代码:

#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=100010;
typedef long long ll;
const ll mod=20110911*2;
#define lson L,mid,ls
#define rson mid+1,R,rs
ll sm[maxn],ss[maxn],sc[maxn<<2],sd[maxn<<2],siid[maxn<<2];
ll sic[maxn<<2],sid[maxn<<2],ac[maxn<<2],ad[maxn<<2];
ll asc,aic,asd,aid,aiid;
void addc(int L,int R,int rt,ll d)
{
    ac[rt]=(ac[rt]+d)%mod;
    sc[rt]=(sc[rt]+(R-L+1)*d)%mod;
    sic[rt]=(sic[rt]+(sm[R]-sm[L-1])*d)%mod;
}
void addd(int L,int R,int rt,ll d)
{
    ad[rt]=(ad[rt]+d)%mod;
    sd[rt]=(sd[rt]+(R-L+1)*d)%mod;
    sid[rt]=(sid[rt]+(sm[R]-sm[L-1])*d)%mod;
    siid[rt]=(siid[rt]+(ss[R]-ss[L-1])*d)%mod;
}
void PushDown(int L,int R,int rt)
{
    int ls=rt<<1,rs=ls|1,mid=(L+R)>>1;
    if(ad[rt])
        addd(lson,ad[rt]),addd(rson,ad[rt]),ad[rt]=0;
    if(ac[rt])
        addc(lson,ac[rt]),addc(rson,ac[rt]),ac[rt]=0;
}
void PushUp(int rt)
{
    int ls=rt<<1,rs=ls|1;
    sc[rt]=(sc[ls]+sc[rs])%mod;
    sic[rt]=(sic[ls]+sic[rs])%mod;
    sd[rt]=(sd[ls]+sd[rs])%mod;
    sid[rt]=(sid[ls]+sid[rs])%mod;
    siid[rt]=(siid[ls]+siid[rs])%mod;
}
void build(int L,int R,int rt)
{
    ac[rt]=ad[rt]=0;
    if(L==R)
    {
        scanf("%I64d%I64d",&sc[rt],&sd[rt]);
        sic[rt]=(L*sc[rt])%mod;
        sid[rt]=(L*sd[rt])%mod;
        siid[rt]=(sid[rt]*L)%mod;
        return;
    }
    int ls=rt<<1,rs=ls|1,mid=(L+R)>>1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void update(int L,int R,int rt,int l,int r,ll d,int op)
{
    if(l<=L&&R<=r)
    {
        if(op)
            addd(L,R,rt,d);
        else
            addc(L,R,rt,d);
        return;
    }
    int ls=rt<<1,rs=ls|1,mid=(L+R)>>1;
    PushDown(L,R,rt);
    if(l<=mid)
        update(lson,l,r,d,op);
    if(r>mid)
        update(rson,l,r,d,op);
    PushUp(rt);
    //printf("%d->%d sc")
}
void qu(int L,int R,int rt,int l,int r)
{
    if(l<=L&&R<=r)
    {
        asc=(asc+sc[rt])%mod;
        aic=(aic+sic[rt])%mod;
        asd=(asd+sd[rt])%mod;
        aid=(aid+sid[rt])%mod;
        aiid=(aiid+siid[rt])%mod;
        return;
    }
    int ls=rt<<1,rs=ls|1,mid=(L+R)>>1;
    PushDown(L,R,rt);
    if(l<=mid)
        qu(lson,l,r);
    if(r>mid)
        qu(rson,l,r);
    PushUp(rt);
}
int main()
{
    int i,t,n,q,x,y,z,cas=1;
    char cmd[20];
    for(i=1;i<maxn;i++)
    {
        sm[i]=(sm[i-1]+i)%mod;
        ss[i]=(ss[i-1]+(ll)i*i)%mod;
    }
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        build(1,n,1);
        scanf("%d",&q);
        printf("Case %d:\n",cas++);
        while(q--)
        {
            asc=aic=asd=aid=aiid=0;
            scanf("%s%d%d",cmd,&x,&y);
            if(cmd[0]!='Q')
                scanf("%d",&z);
            if(cmd[2]=='s')
                update(1,n,1,x,y,z,0);
            else if(cmd[2]=='l')
                update(1,n,1,x,y,z,1);
            else
            {
                qu(1,n,1,x,y);
                ll ans=((ll)y*(y+1)*asd-(2*y+1)*aid+aiid)%mod;
                ans-=2*((y+1)*asc-aic);
                ans%=mod;
                ans=(ans+mod)%mod;
                //printf("asc %I64d aic %I64d asd %I64d aid %I64d aiid %I64d\n",asc,aic,asd,aid,aiid);
                printf("%I64d\n",ans/2);
            }
        }
    }
    return 0;
}
时间: 2024-08-18 13:42:49

hdu 4037 Development Value(线段树维护数学公式)的相关文章

HDU 6155 Subsequence Count 线段树维护矩阵

Subsequence Count Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others) Problem Description Given a binary string S[1,...,N] (i.e. a sequence of 0's and 1's), and Q queries on the string. There are two types of querie

HDU 2795 Billboard 【线段树维护区间最大值&amp;&amp;查询变形】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2795 Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 28743    Accepted Submission(s): 11651 Problem Description At the entrance to the un

HDU - 4614 【二分+线段树维护】

Vases and Flowers Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 3263    Accepted Submission(s): 1299 Problem Description Alice is so popular that she can receive many flowers everyday. She has

HDU 5068 Harry And Math Teacher( 矩阵乘法 + 线段树维护 )

HDU 5068 Harry And Math Teacher( 矩阵乘法 + 线段树维护 ) 题意: 首先是这题题意理解错误,,其次是这题无法理解状态... 已经不是英文有多烂的情况了,是中文没学好啊.....大学不学语文才是真正的硬伤啊 题目意思 有一个城堡有很多层楼, 每层楼有2个门,每个门里面又有两个楼梯,可以通往上一层的两个门 问,从x层楼到y层楼有多少中方法(不能返回) 具体看图吧,,,已经不会说话了 1 #include <cstdio> 2 #include <cstri

hdu 2795 Billboard(线段树)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10890    Accepted Submission(s): 4827 Problem Description At the entrance to the university, there is a huge rectangular billboard of

HDU 3954 Level up 线段树

---NotOnlySuccess 出的题--- 看了题之后觉得和HDU 4027有点像,给的K很小,只有10,目测只要有人升级的时候直接更新到叶子节点就ok了.不过不同于HDU 4027 的是,那题每一次更新都相当于这题的一次升级操作,这题里面可能会出现一次操作之后没有升级和出现升级两种情况,一时半会没了思路. 无奈去搜题解,发现我只要维护一个区间当中距离升级最近的人所需要的基础升级经验,即不算等级加成的裸的升级经验,如果在一次涨经验之后,出现当前区间当中有人会升级,直接将每一个要升级的人更新

HDU 3308 LCIS(线段树)

Problem Description Given n integers.You have two operations:U A B: replace the Ath number by B. (index counting from 0)Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b]. Input T in the first line, indicating

hdu 5700区间交(线段树)

区间交 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 849    Accepted Submission(s): 377 Problem Description 小A有一个含有n个非负整数的数列与m个区间.每个区间可以表示为li,ri. 它想选择其中k个区间, 使得这些区间的交的那些位置所对应的数的和最大. 例如样例中,选择[2,5]

HDU 3265 Posters(线段树)

HDU 3265 Posters 题目链接 题意:给定一些矩形海报,中间有孔,求贴海报的之后的海报覆盖面积并 思路:海报一张可以切割成4个矩形,然后就是普通的矩形面积并了,利用线段树维护即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N = 50005; struct Node { i