P5524 [Ynoi2012] NOIP2015 充满了希望
Genius_Star · · 题解
最简单的 Ynoi?
思路:
先考虑没有交换操作时怎么做。
显然由于是区间覆盖,那么查询一个位置
那么询问一次执行
那如果有交换操作呢?你发现本质上就是交换一下
于是用线段树维护区间最大值(赋值),方便查询
完整代码:
#include<bits/stdc++.h>
#define ls(k) k << 1
#define rs(k) k << 1 | 1
#define lowbit(x) x & (-x)
#define fi first
#define se second
#define popcnt(x) __builtin_popcount(x)
#define open(s1, s2) freopen(s1, "r", stdin), freopen(s2, "w", stdout);
using namespace std;
typedef __int128 __;
typedef long double lb;
typedef double db;
typedef unsigned long long ull;
typedef long long ll;
bool Begin;
const int N = 1e6 + 10;
inline ll read(){
ll x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')
f = -1;
c = getchar();
}
while(c >= '0' && c <= '9'){
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return x * f;
}
inline void write(ll x){
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
int n, m, q, op, x, y, l, r;
int id[N];
ll ans[N];
vector<pair<int, int>> E[N];
vector<pair<int, int>> Q[N];
struct Node{
int l, r;
int mx, tag;
}X[N << 2];
inline void chkmx(int k, int v){
X[k].mx = v;
X[k].tag = v;
}
inline void push_down(int k){
if(X[k].tag){
chkmx(k << 1, X[k].tag);
chkmx(k << 1 | 1, X[k].tag);
X[k].tag = 0;
}
}
inline void build(int k, int l, int r){
X[k].l = l, X[k].r = r;
if(l == r)
return ;
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
}
inline void update(int k, int l, int r, int v){
if(X[k].l == l && r == X[k].r){
chkmx(k, v);
return ;
}
push_down(k);
int mid = (X[k].l + X[k].r) >> 1;
if(r <= mid)
update(k << 1, l, r, v);
else if(l > mid)
update(k << 1 | 1, l, r, v);
else{
update(k << 1, l, mid, v);
update(k << 1 | 1, mid + 1, r, v);
}
}
inline int ask(int k, int i){
if(X[k].l == i && i == X[k].r)
return X[k].mx;
push_down(k);
int mid = (X[k].l + X[k].r) >> 1;
if(i <= mid)
return ask(k << 1, i);
else
return ask(k << 1 | 1, i);
}
namespace BIT{
ll a[N];
inline void add(int x, int v){
for(int i = x; i <= m; i += lowbit(i))
a[i] += v;
}
inline ll ask(int x){
ll sum = 0;
for(int i = x; i; i -= lowbit(i))
sum += a[i];
return sum;
}
};
int main() {
n = read(), m = read(), q = read();
build(1, 1, n);
for(int i = 1; i <= m; ++i){
op = read();
if(op == 2){
l = read(), r = read(), x = read();
id[i] = x;
update(1, l, r, i);
}
else if(op == 1){
x = read(), y = read();
int a = ask(1, x), b = ask(1, y);
update(1, x, x, b);
update(1, y, y, a);
}
else{
x = read();
int a = ask(1, x);
if(a)
E[i].push_back({a, id[a]});
}
}
for(int i = 1; i <= q; ++i){
l = read(), r = read();
Q[r].push_back({l, i});
}
for(int i = 1; i <= m; ++i){
for(auto t : E[i])
BIT::add(t.fi, t.se);
for(auto t : Q[i])
ans[t.se] = BIT::ask(i) - BIT::ask(t.fi - 1);
}
for(int i = 1; i <= q; ++i){
write(ans[i]);
putchar('\n');
}
return 0;
}