Codeforces 627B Factory Repairs 线段树
2016-03-15 12:31
471 查看
题目:627B - Factory Repairs
Input
The first line contains five integers n,
k, a,
b, and q (1 ≤ k ≤ n ≤ 200 000,
1 ≤ b < a ≤ 10 000,
1 ≤ q ≤ 200 000) — the number of days, the length of the repair time, the production rates of the factory, and the number of updates, respectively.
The next q lines contain the descriptions of the queries. Each query is of one of the following two forms:
1 di
ai (1 ≤ di ≤ n,
1 ≤ ai ≤ 10 000), representing an update of
ai orders on day
di, or
2 pi (1 ≤ pi ≤ n - k + 1), representing a question: at the moment, how many orders
could be filled if the factory decided to commence repairs on day
pi?
It's guaranteed that the input will contain at least one query of the second type.
Output
For each query of the second type, print a line containing a single integer — the maximum number of orders that the factory can fill over all
n days.
题意:
有个工厂在n天内生产产品,本来机器是坏的,每天只能生产b件,修一次需要k天,修完后,每天可以生产a件,其中有q次询问,1开头,后面是d和ai,表示第d天有个ai的订单
2开头,后面有个d,表示这一天开始修理机器。每次2的时候,问工厂n天可以出售多少件产品?
分析:
线段树基础题型,1是单点增减,2是区间求和,sum二维数组分别维护修理前和修理后的生产效率,但是要注意都不可以超过订单额度,而且同一天可能有多个订单
区间求和的是修理前的天数和修理后的天数,相加即可
#include <bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int n,k,a,b;
const int N=2e5+1;
int sum[N<<2][2];
void pushup(int rt)
{
sum[rt][0]=sum[rt<<1][0]+sum[rt<<1|1][0];
sum[rt][1]=sum[rt<<1][1]+sum[rt<<1|1][1];
}
void update(int d,int ai,int l,int r,int rt)
{
if(d==l&&l==r){
sum[rt][0]=ai+sum[rt][0]>b?b:ai+sum[rt][0];
sum[rt][1]=ai+sum[rt][1]>a?a:ai+sum[rt][1];
return;
}
int m=(l+r)>>1;
if(d<=m)update(d,ai,lson);
else update(d,ai,rson);
pushup(rt);
}
int query(int L,int R,int id,int l,int r,int rt)
{
if(L<=l&&r<=R){
return sum[rt][id];
}
int ans=0;
int m=(l+r)>>1;
if(L<=m)ans+=query(L,R,id,lson);
if(m<R)ans+=query(L,R,id,rson);
return ans;
}
int main()
{
int q,op,d,ai;
//freopen("f.txt","r",stdin);
memset(sum,0,sizeof(sum));
scanf("%d%d%d%d%d",&n,&k,&a,&b,&q);
for(int i=0;i<q;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d",&d,&ai);
update(d,ai,1,n,1);
}
else{
scanf("%d",&d);
int ans=0;
if(d>1)ans=query(1,d-1,0,1,n,1);
// cout<<ans<<endl;
if(d+k<=n) ans+=query(d+k,n,1,1,n,1);
printf("%d\n",ans);
}
}
return 0;
}
Input
The first line contains five integers n,
k, a,
b, and q (1 ≤ k ≤ n ≤ 200 000,
1 ≤ b < a ≤ 10 000,
1 ≤ q ≤ 200 000) — the number of days, the length of the repair time, the production rates of the factory, and the number of updates, respectively.
The next q lines contain the descriptions of the queries. Each query is of one of the following two forms:
1 di
ai (1 ≤ di ≤ n,
1 ≤ ai ≤ 10 000), representing an update of
ai orders on day
di, or
2 pi (1 ≤ pi ≤ n - k + 1), representing a question: at the moment, how many orders
could be filled if the factory decided to commence repairs on day
pi?
It's guaranteed that the input will contain at least one query of the second type.
Output
For each query of the second type, print a line containing a single integer — the maximum number of orders that the factory can fill over all
n days.
题意:
有个工厂在n天内生产产品,本来机器是坏的,每天只能生产b件,修一次需要k天,修完后,每天可以生产a件,其中有q次询问,1开头,后面是d和ai,表示第d天有个ai的订单
2开头,后面有个d,表示这一天开始修理机器。每次2的时候,问工厂n天可以出售多少件产品?
分析:
线段树基础题型,1是单点增减,2是区间求和,sum二维数组分别维护修理前和修理后的生产效率,但是要注意都不可以超过订单额度,而且同一天可能有多个订单
区间求和的是修理前的天数和修理后的天数,相加即可
#include <bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int n,k,a,b;
const int N=2e5+1;
int sum[N<<2][2];
void pushup(int rt)
{
sum[rt][0]=sum[rt<<1][0]+sum[rt<<1|1][0];
sum[rt][1]=sum[rt<<1][1]+sum[rt<<1|1][1];
}
void update(int d,int ai,int l,int r,int rt)
{
if(d==l&&l==r){
sum[rt][0]=ai+sum[rt][0]>b?b:ai+sum[rt][0];
sum[rt][1]=ai+sum[rt][1]>a?a:ai+sum[rt][1];
return;
}
int m=(l+r)>>1;
if(d<=m)update(d,ai,lson);
else update(d,ai,rson);
pushup(rt);
}
int query(int L,int R,int id,int l,int r,int rt)
{
if(L<=l&&r<=R){
return sum[rt][id];
}
int ans=0;
int m=(l+r)>>1;
if(L<=m)ans+=query(L,R,id,lson);
if(m<R)ans+=query(L,R,id,rson);
return ans;
}
int main()
{
int q,op,d,ai;
//freopen("f.txt","r",stdin);
memset(sum,0,sizeof(sum));
scanf("%d%d%d%d%d",&n,&k,&a,&b,&q);
for(int i=0;i<q;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d",&d,&ai);
update(d,ai,1,n,1);
}
else{
scanf("%d",&d);
int ans=0;
if(d>1)ans=query(1,d-1,0,1,n,1);
// cout<<ans<<endl;
if(d+k<=n) ans+=query(d+k,n,1,1,n,1);
printf("%d\n",ans);
}
}
return 0;
}
相关文章推荐
- git中Please enter a commit message to explain why this merge is necessary.
- Mongo运行错误:Failed to connect 127.0.0.1:27017,reason:errno:10061由于目标计算机积极拒绝,无法连接
- dmraid
- 磁盘管理之RAID
- ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
- 如何进行rails性能优化
- time_wait和close_wait状态
- <interface declaration>, <parcelable declaration>, AidlTokenType.import or AidlTokenType.package ...
- LeetCode: Container With Most Water
- leetcode 217. Contains Duplicate
- Android Volley完全解析(二),使用Volley加载网络图片 转载:http://blog.csdn.net/guolin_blog/article/details/174
- Android Volley完全解析(一),初识Volley的基本用法 转载地址:http://blog.csdn.net/guolin_blog/article/details/17482095
- air jordan shoes jordan new shoes
- 人机大战输赢不重要!重要的是说人话
- Time.timeScale 对 协程WaitForSeconds的影响
- LeetCode #11 Container With Most Water 最大容器 解题小节
- #345 Div2 B. Beautiful Paintings
- 在 Windows 上遇到非常多 TIME_WAIT 連線時應如何處理
- 服务器TIME_WAIT和CLOSE_WAIT详解和解决办法
- 我的人工智能学习之路(1)