【题目】
| Time Limit: 6000/3000 MS (Java/Others) |
| Memory Limit: 502768/502768 K (Java/Others) |
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:
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
【题意】
两列数字a列初始为0,b列给定,可进行两种操作
1.把区间l到r的的a列数字加1
2.询问 l到r区间 ai/bi 下取整值 的和
【题解】
这个倒着想来处理下取整的方法可太机智了,,,我自己没想到这样维护。
【AC代码】
#include<bits/stdc++.h>
using namespace std;
#define ln (node<<1)
#define rn (node<<1)|1
#define len r-l+1
int const maxn=100005;
int b[maxn],z[maxn<<2],lazy[maxn<<2],sum[maxn<<2],lrange,rrange,ans;
int n,q;
void add(int l,int r,int node,int x){
lazy[node]+=x;
z[node]-=x;
}
void pushdown(int l,int r,int node){//改为当前节点对,对下面的打标记
if(!lazy[node])return ;
int mid=(l+r)>>1;
add(l,mid,ln,lazy[node]);
add(mid+1,r,rn,lazy[node]);
lazy[node]=0;
}
void update(int l,int r,int node){
sum[node]=sum[ln]+sum[rn];
z[node]=min(z[ln],z[rn]);
}
void change(int l,int r,int node){
if(l>=lrange&&r<=rrange&&z[node]!=1){
lazy[node]++;
z[node]--;
return ;
}
else if(l==r&&z[node]==1){
z[node]=b[l];sum[node]++;lazy[node]=0;
return ;
}
int mid=(l+r)>>1;
pushdown(l,r,node);
if(lrange<=mid)change(l,mid,ln);
if(mid<rrange)change(mid+1,r,rn);
update(l,r,node);
}
void query(int l,int r,int node){
pushdown(l,r,node);
if(l>=lrange&&r<=rrange){
ans+=sum[node];
return;
}
int mid=(l+r)>>1;
if(lrange<=mid)query(l,mid,ln);
if(mid+1<=rrange)query(mid+1,r,rn);
}
inline int get_num(){
int num=0;
char ch;
bool flag=false;
ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')flag=true; ch=getchar();}
while(ch>='0'&&ch<='9'){num=(num<<1)+(num<<3)+ch-'0';ch=getchar();}
if(flag)return num*-1;
return num;
}
void built(int l,int r,int node){
if(l==r){
z[node]=b[l];return ;
}
int mid=(l+r)>>1;
built(l,mid,ln);
built(mid+1,r,rn);
z[node]=min(z[ln],z[rn]);
}
int main(){
while(scanf("%d%d",&n,&q)!=EOF){
for(int i=1;i<=n;i++)b[i]=get_num();
built(1,n,1);
int m=n<<2;//记得初始化,把lazy也清0
for(int i=1;i<=m;i++)lazy[i]= 0,sum[i]=0;
string s;
for(int k=1;k<=q;k++){
cin>>s;
lrange=get_num();rrange=get_num();
if(s[0]=='a'){
change(1,n,1);
}
else{
ans=0;
query(1,n,1);
printf("%d\n",ans);
}
}
}
return 0;
}
[hdu 6315] Naive Operations 线段树+思维 2018多校2
原文:https://www.cnblogs.com/conver/p/12262125.html