杭电多校第二场 hdu 6315 Naive Operations 线段树变形
杭电多校第二场 hdu 6315 Naive Operations 线段树变形
Naive Operations
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 502768/502768 K (Java/Others)
Total Submission(s): 2114 Accepted Submission(s): 915
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⌋
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.
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
1
2
4
4
6
#include <map> #include <set> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <vector> #include <string> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define ls (r<<1) #define rs (r<<1|1) #define debug(a) cout << #a << " " << a << endl using namespace std; typedef long long ll; const ll maxn = 1e5 + 1000; const ll mod = 1e9 + 7; struct node { ll fg; ll s; //一段区间总和 ll mv; //记录最小值 }root[4*maxn]; ll b[maxn], n, m, le, ri; char s[10]; void update( ll r ) { root[r].mv = min( root[ls].mv, root[rs].mv ); root[r].s = root[ls].s + root[rs].s; } void setf( ll r, ll f ) { root[r].fg += f; root[r].mv += f; } void build( ll r, ll le, ll ri ) { root[r].fg = 0; if( le == ri ) { root[r].mv = b[le]-1; root[r].s = 0; } else { ll mid = ( le + ri ) >> 1; build( ls, le, mid ); build( rs, mid+1, ri ); update(r); } } void push( ll r ) { if( root[r].fg ) { //fg为-1进行操作,将左右子树最小值置为-1,同时将左右子树fg标记为-1 setf( ls, root[r].fg ); setf( rs, root[r].fg ); root[r].fg = 0; } } ll query( ll r, ll le, ll ri, ll tl, ll tr ) { if( tl == le && tr == ri ) { return root[r].s; } else { push(r); ll mid = ( le + ri ) >> 1; if( tr <= mid ) { return query( ls, le, mid, tl, tr ); } else if( tl > mid ) { return query( rs, mid+1, ri, tl, tr ); } else { return query( ls, le, mid, tl, mid ) + query( rs, mid+1, ri, mid+1, tr ); } } } void modify( ll r, ll le, ll ri, ll tl, ll tr ) { if( tl > tr ) { return; } if( tl == le && tr == ri ) { if( root[r].mv > 0 ) { root[r].mv --, root[r].fg --; } else { if( tl == tr ) { root[r].mv = b[le]-1; root[r].s ++; } else { push(r); ll mid = ( le + ri ) >> 1; if( root[ls].mv == 0 ) { modify( ls, le, mid, tl, mid ); } else { setf( ls, -1 ); } if( root[rs].mv == 0 ) { modify( rs, mid+1, ri, mid+1, tr ); } else { setf( rs, -1 ); } update(r); } } } else { push(r); ll mid = ( le + ri ) >> 1; if( tr <= mid ) { modify( ls, le, mid, tl, tr ); } else if( tl > mid ) { modify( rs, mid+1, ri, tl, tr ); } else { modify( ls, le, mid, tl, mid ), modify( rs, mid+1, ri, mid+1, tr ); } update(r); } } int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); while( scanf("%lld%lld",&n,&m) != EOF ) { for( ll i = 1; i <= n; i ++ ) { scanf("%lld",&b[i]); } build(1,1,n); for( ll i = 1; i <= m; i ++ ) { scanf("%s%lld%lld",s,&le,&ri); if( s[0] == 'a' ) { modify( 1, 1, n, le, ri ); } else { printf("%lld\n",query(1,1,n,le,ri)); } } } return 0; }