题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6315
Naive Operations
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 502768/502768 K (Java/Others)
Total Submission(s): 1855 Accepted Submission(s): 803
Problem Description
In a galaxy far, far away, there are two integer sequence a and b of length n.
b is a static permutation of 1 to n. Initially a is filled with zeroes.
There are two kind of operations:
1. add l r: add one for al,al+1...ar
2. query l r: query ∑ri=l⌊ai/bi⌋
Input
There are multiple test cases, please read till the end of input file.
For each test case, in the first line, two integers n,q, representing the length of a,b and the number of queries.
In the second line, n integers separated by spaces, representing permutation b.
In the following q lines, each line is either in the form 'add l r' or 'query l r', representing an operation.
1≤n,q≤100000, 1≤l≤r≤n, there're no more than 5 test cases.
Output
Output the answer for each 'query', each one line.
Sample Input
5 12
1 5 2 4 3
add 1 4
query 1 4
add 2 5
query 2 5
add 3 5
query 1 5
add 2 4
query 1 4
add 2 5
query 2 5
add 2 2
query 1 5
Sample Output
1 1 2 4 4 6
Source
2018 Multi-University Training Contest 2
题意:给你n个数字,然后q次询问,可能是add或者query。刚开始n个数字都是B数组,然后add操作shi是将A数组(刚开始全部都是0)L----R区间都+1。query操作是将L----R 区间的A[i]/B[i]求和输出。
思路:看到区间修改区间求解问题应该是线段树一类的,但是怎么去求A[i]/B[i]。维护区间最小值,当最小值为0的时候,区间贡献值增加1,暴力下推lazy标记。但是不知道为啥没T。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
const int Maxn=1e6+5;
LL a[maxn];
LL valu[Maxn];//区间最小值
LL sum[Maxn]; //区间贡献
LL lazy[Maxn];
void pushup(int id)//从下往上更新
{
sum[id] = sum[id<<1] + sum[id<<1|1];
valu[id] = min(valu[id<<1] , valu[id<<1|1]);
}
void build(int l,int r,int id)//建树
{
sum[id]=0;
lazy[id]=0;
if(l==r)
{
valu[id] = a[l];
return ;
}
int mid = (l+r) >> 1;
build(l,mid,id<<1);
build(mid+1,r,id<<1|1);
pushup(id);
}
void pushdown(int id)//下推
{
if(lazy[id])
{
lazy[id<<1] = lazy[id<<1] + lazy[id];
lazy[id<<1|1] = lazy[id<<1|1] + lazy[id];
valu[id<<1] = valu[id<<1] - lazy[id];
valu[id<<1|1] = valu[id<<1|1] - lazy[id];
lazy[id]=0;
}
}
void Change(int l,int r,int id)
{
if(l==r)
{
lazy[id]=0;
valu[id]=a[l];//增加贡献 取模
sum[id]++;
return ;
}
pushdown(id);
int mid = (l+r) >> 1;
if(valu[id<<1] == 0 )
Change(l,mid,id<<1);
if(valu[id<<1|1] == 0)
Change(mid+1,r,id<<1|1);
pushup(id);
}
void update(int L,int R,int l,int r,int id)//更新
{
if(L<=l && R>=r)
{
lazy[id]++;
valu[id]--;
if(valu[id]==0)//对区间贡献+1
Change(l,r,id);
return ;
}
pushdown(id);
int mid=(l+r) >> 1;
if(L<=mid)
update(L,R,l,mid,id<<1);
if(R>mid)
update(L,R,mid+1,r,id<<1|1);
pushup(id);
}
LL query(int L,int R,int l,int r,int id)//查询
{
if(L<=l && R>=r)
return sum[id];
pushdown(id);//将存的lazy下推
LL ans=0;
int mid= (l+r) >>1;
if(L<=mid)
ans = ans +query(L,R,l,mid,id<<1);
if(R>mid)
ans= ans + query (L,R ,mid+1 ,r ,id<<1|1);
return ans;
}
int main()
{
int n,q,x,y;
char s[10];
while(scanf("%d%d",&n,&q)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,n,1);
while(q--)
{
scanf("%s%d%d",s,&x,&y);
if(s[0]=='a')
update(x,y,1,n,1);
else
printf("%lld\n",query(x,y,1,n,1));
}
}
return 0;
}