QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#696270 | #8139. Ayano and sequences | Lavender_Field | WA | 3ms | 46916kb | C++20 | 5.7kb | 2024-10-31 21:59:25 | 2024-10-31 21:59:37 |
Judging History
answer
// 先通过 odt 做出询问矩形,再直接做出更新矩形,然后扫描线
// 扫描线需要查询历史 sum。
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i = a; i <= b; ++i)
using namespace std;
typedef unsigned long long ull;
inline int rd() {
int r = 0; bool w = false; char ch = getchar();
while( ch < '0' || ch > '9' ) w = !(ch^45), ch = getchar();
while( ch >= '0' && ch <= '9' ) r = (r<<1) + (r<<3) + (ch^48), ch = getchar();
return w ? -r : r;
}
#define MAXN 500000
int n, q;
int a[MAXN+5];
int globalTime = 1;
ull ans[MAXN+5];
vector<tuple<pair<int,int>, bool, int> > queryBuc[MAXN+5];
// bool 1 代表加,0 代表减
vector<pair<pair<int, int>, int> > modifyBuc[MAXN+5];
struct Node_t {
int l, r;
mutable int v, t;
Node_t(int li, int ri, int vi, int ti): l(li), r(ri), v(vi), t(ti) {}
bool operator < (const Node_t &other) const {
return l < other.l;
}
};
// lower_bound: >= 当前值。如果有 x,则返回的是 x;否则返回的是大于 x 的。
std::set<Node_t> odt;
auto odt_split( int x ) {
auto it = odt.lower_bound(Node_t(x, 0, 0, 0));
if( it != odt.end() && it->l == x ) return it;
--it;
Node_t new1 = Node_t(it->l, x-1, it->v, it->t),
new2 = Node_t(x, it->r, it->v, it->t);
odt.erase(it);
odt.insert(new1);
return odt.insert(new2).first;
}
// globalTime 表示当前循环所在的时间,生成一个矩形是从 Node_t.t 到 globalTime-1
void odt_assign( int l , int r , int v ) {
auto itr = odt_split(r+1), itl = odt_split(l);
for(auto it = itl; it != itr; ++it) {
if( it->v == 0 ) continue;
// printf("rect: %d %d %d %d %d\n", it->l, it->r, it->t, globalTime-1, it->v);
queryBuc[globalTime-1].push_back(make_tuple(make_pair(it->l, it->r), 1, it->v));
queryBuc[it->t-1].push_back(make_tuple(make_pair(it->l, it->r), 0, it->v));
}
odt.erase(itl, itr);
odt.insert(Node_t(l, r, v, globalTime));
}
template<typename T>
struct Seg {
T a[MAXN*4+5];
T lz[MAXN*4+5];
Seg() {
memset(a, 0, sizeof(a));
}
#define lson (p<<1)
#define rson ((p<<1)+1)
void pushdown( int p , int l , int r ) {
if( lz[p] ) {
int mid = (l+r) >> 1;
int lsonl = mid - l + 1, rsonl = r - mid;
lz[lson] += lz[p];
a[lson] += lsonl * lz[p];
lz[rson] += lz[p];
a[rson] += rsonl * lz[p];
lz[p] = 0;
}
}
void pushup( int p ) {
a[p] = a[lson] + a[rson];
}
void update( int l, int r, T k, int L = 1, int R = n, int p = 1 ) {
if( l == L && r == R ) {
a[p] += k * (R-L+1);
lz[p] += k;
return;
}
int mid = (L + R) >> 1;
pushdown(p, L, R);
if( r <= mid ) update(l, r, k, L, mid, lson);
else if( l > mid ) update(l, r, k, mid+1, R, rson);
else {
update(l, mid, k, L, mid, lson);
update(mid+1, r, k, mid+1, R, rson);
}
pushup(p);
}
T query( int l , int r , int L = 1 , int R = n , int p = 1 ) {
if( l == L && r == R ) {
return a[p];
}
int mid = (L+R)>>1;
pushdown(p, L, R);
if( r <= mid ) return query(l, r, L, mid, lson);
if( l > mid ) return query(l, r, mid+1, R, rson);
return query(l, mid, L, mid, lson) + query(mid+1, r, mid+1, R, rson);
}
#undef lson
#undef rson
};
Seg<ull> aseg, cseg;
int arra[MAXN+5], arrc[MAXN+5];
int main() {
// n = 5;
// aseg.update(1, 3, 2);
// aseg.update(2, 5, 1);
// cout << aseg.query(1, 1) << endl;
// return 0;
// freopen("data.txt", "r", stdin);
odt.insert(Node_t(1, n+1, 0, 0));
n = rd(), q = rd();
FOR(i,1,n) a[i] = rd();
FOR(i,1,n) {
int lp = i;
while( lp < n && a[lp+1] == a[i] ) ++lp;
odt_assign(i, lp, a[i]);
i = lp;
}
FOR(i,1,q) {
globalTime = i;
int opt = rd(), l = rd(), r = rd(), w = rd();
if( opt == 1 ) {
odt_assign(l, r, w);
} else {
modifyBuc[i].push_back(make_pair(make_pair(l, r), w));
}
}
globalTime = q+1;
odt_assign(1, n+1, 0);
FOR(i,1,q) {
for(auto v: modifyBuc[i]) {
aseg.update(v.first.first, v.first.second, v.second);
cseg.update(v.first.first, v.first.second, -v.second * (i-1));
// for(int j = v.first.first; j <= v.first.second; ++j) {
// arra[j] += v.second;
// arrc[j] -= v.second * (i-1);
// }
}
// for(int j = 1; j <= n; ++j) printf("%d ", arra[j]);
// putchar('\n');
// for(int j = 1; j <= n; ++j) printf("%d ", aseg.query(j, j)); printf("%d", aseg.query(1, n));
// putchar('\n');
for(auto v: queryBuc[i]) {
auto [s, typ, idx] = v;
// for(int j = s.first; j <= s.second; ++j) {
// ans[idx] += (arrc[j] + i * arra[j]) * (typ ? 1 : -1);
// }
ans[idx] += (cseg.query(s.first, s.second) + i * aseg.query(s.first, s.second)) * (typ ? 1 : -1);
// if( typ ) ans[idx] += cseg.query(s.first, s.second) + i * aseg.query(s.first, s.second);
// else ans[idx] -= cseg.query(s.first, s.second) + i * aseg.query(s.first, s.second);
}
}
FOR(i,1,n) printf("%llu ", ans[i]);
return 0;
}
/*
5 6
1 2 3 4 5
2 2 4 1
1 2 3 3
2 3 4 3
1 3 5 4
2 1 5 2
1 1 3 2
2 2 2 4 4
1 3 4 4 4
1 3 4 4 4
1 3 3 4 5
1 3 3 4 5
1 2 3 4 5
1 2 3 4 5
*/
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 46856kb
input:
5 6 1 2 3 4 5 2 2 4 1 1 2 3 3 2 3 4 3 1 3 5 4 2 1 5 2 1 1 3 2
output:
2 12 12 36 0
result:
ok single line: '2 12 12 36 0 '
Test #2:
score: -100
Wrong Answer
time: 2ms
memory: 46916kb
input:
10 10 9 2 8 8 6 5 4 8 5 3 2 2 6 268792718 2 7 8 125908043 2 2 3 150414369 2 6 10 856168102 2 4 5 274667941 1 1 9 6 2 2 6 646837311 2 6 6 105650419 2 7 9 254786900 2 1 7 73936815
output:
0 1795206697 10288144010 6510935672 13358570590 67746528113 0 9924773900 0 0
result:
wrong answer 1st lines differ - expected: '0 1795206697 5993176714 221596...98 46271691633 0 5629806604 0 0', found: '0 1795206697 10288144010 65109...0 67746528113 0 9924773900 0 0 '