記錄一下 \(zcxxxxx\) 的爆零技巧,以供大家一起爆零 \(QWQ\)
2022.11.14
都快要考試了我還掛大分,我就是個菜雞
考場上用了 set,堆,pair套pair,pbds,還有直接存下標比較
然后發現 pair 套 pair 是跑的最快的。
所以以后結構體內需要按某種方式排序的時候,可以試一試pair套pair,但是只適用於元素較少的情況,因為太繁瑣……
具體實踐了一下:
set 和 pair
bool check2 (int mid) {
int k = mid, v = ans1;
set <pair <int, pair <int, int> > > s;
for (int i = 1; i <= n; ++ i) {
if (v >= a[i].a) {
s.insert (make_pair (a[i].b, make_pair (a[i].d, a[i].c)));
while (i + 1 <= n && a[i + 1].a <= v) {
++ i;
s.insert (make_pair (a[i].b, make_pair (a[i].d, a[i].c)));
}
}
while (s.size ()) {
int x = s.begin ()->first, y = s.begin ()->second.first, z = s.begin ()->second.second;
s.erase (s.begin ());
if (x <= k) k += y, v += z;
else return 0;
}
} return 1;
}
堆
struct node1 {
int a, b, c;
bool operator < (const node1 &x) const {
if (x.a == a) {
return x.b < b;
}
return x.a < a;
}
};
bool check2 (int mid) {
ll k = mid, v = ans1;
priority_queue <node1> s;
for (int i = 1; i <= n; ++ i) {
if (v >= a[i].a) {
s.push ((node1){a[i].b, a[i].d, a[i].c});
while (i + 1 <= n && a[i + 1].a <= v) {
++ i;
s.push ((node1){a[i].b, a[i].d, a[i].c});
}
}
while (s.size ()) {
int x = s.top ().a, y = s.top ().b, z = s.top ().c;
// cout << x <<" ";
s.pop ();
if (x <= k) k += y, v += z;
else return 0;
}
} return 1;
}
堆 存下標
struct node1 {
int a, b, c;
bool operator < (const node1 &x) const {
if (x.a == a) {
return x.b < b;
}
return x.a < a;
}
};
bool check2 (int mid) {
ll k = mid, v = ans1;
priority_queue <node1> s;
for (int i = 1; i <= n; ++ i) {
if (v >= a[i].a) {
s.push ((node1){a[i].b, a[i].d, a[i].c});
while (i + 1 <= n && a[i + 1].a <= v) {
++ i;
s.push ((node1){a[i].b, a[i].d, a[i].c});
}
}
while (s.size ()) {
int x = s.top ().a, y = s.top ().b, z = s.top ().c;
// cout << x <<" ";
s.pop ();
if (x <= k) k += y, v += z;
else return 0;
}
} return 1;
}
手殘數組開小了,全 RE 了。
寫了 O(kn+km) 的,然后開了207*507,手真的殘。
寫了一個特別繁瑣的做法。
說實話我都不確定跑出來時個啥東西,以后不要用奇奇怪怪的求解方法,不需要特殊處理的東西盡量不用,寧可多想一會也不要急着去寫。
看了一眼,覺得思路很簡單,然后看了看時間,還剩了一個小時啊,我就決定,不打暴力了,寫正解,於是沒寫出來……於是寄了整場比賽。
就到最后的時候,我是手指冰涼的感覺,打着打着手就突然僵那了,然后看了看還有20分鍾,決心一定能挑出來,然后沒調出來。
以后一定不能莽了……
看見這種大數據結構,一定先寫個暴力。
一個小時打了個這個玩意
# include <bits/stdc++.h>
using namespace std;
const int D = 2e5 + 7;
int n, m;
int v[D], a[D], b[D];
int tv[D << 2], ta[D << 2], tb[D << 2], tgo[D << 2];
int lzyv[D << 2], lzya[D << 2], lzyb[D << 2], lzyt[D << 2];
void pushup (int now) {
tv[now] = tv[now << 1] + tv[now << 1 | 1];
ta[now] = ta[now << 1] + ta[now << 1 | 1];
tb[now] = tb[now << 1] + tb[now << 1 | 1];
tgo[now] = tgo[now << 1] + tgo[now << 1 | 1];
}
void build (int now, int l, int r) {
if (l == r) {
tv[now] = v[l];
ta[now] = a[l];
tb[now] = b[l];
tgo[now] = a[l] * b[l];
return;
}
int mid = l + r >> 1;
build (now << 1, l, mid);
build (now << 1 | 1, mid + 1, r);
pushup (now);
}
void pushdown (int now, int l, int r) {
if (lzyv[now]) {
int mid = l + r >> 1;
int ll = l, lr = mid, rl = mid + 1, rr = r;
lzyv[now << 1] += lzyv[now];
lzyv[now << 1 | 1] += lzyv[now];
tv[now << 1] += (lr - ll + 1) * lzyv[now];
tv[now << 1 | 1] += (rr - rl + 1) * lzyv[now];
}
// if (l == r) {
// cout << l <<" " << lzya[now] << "||\n";
// }
if (lzya[now]) {
int mid = l + r >> 1;
int ll = l, lr = mid, rl = mid + 1, rr = r;
lzya[now << 1] += lzya[now];
lzya[now << 1 | 1] += lzya[now];
ta[now << 1] += (lr - ll + 1) * lzya[now];
ta[now << 1 | 1] += (rr - rl + 1) * lzya[now];
tgo[now << 1] += lzya[now] * tb[now << 1];
tgo[now << 1 | 1] += lzya[now] * tb[now << 1 | 1];
}
if (lzyb[now]) {
int mid = l + r >> 1;
int ll = l, lr = mid, rl = mid + 1, rr = r;
lzyb[now << 1] += lzyb[now];
lzyb[now << 1 | 1] += lzyb[now];
tb[now << 1] += (lr - ll + 1) * lzyb[now];
tb[now << 1 | 1] += (rr - rl + 1) * lzyb[now];
tgo[now << 1] += lzyb[now] * ta[now << 1];
tgo[now << 1 | 1] += lzyb[now] * ta[now << 1 | 1];
}
if (lzyt[now]) {
int mid = l + r >> 1;
int ll = l, lr = mid, rl = mid + 1, rr = r;
lzyt[now << 1] += lzyt[now];
lzyt[now << 1 | 1] += lzyt[now];
tv[now << 1] += tgo[now << 1] * lzyt[now << 1];
tv[now << 1 | 1] += tgo[now << 1 | 1] * lzyt[now << 1 | 1];
}
}
void update (int now, int l, int r, int L, int R, int x) {
pushdown (now, l, r);
if (l == r) {
lzyv[now] += x;
tv[now] += x * (r - l + 1);
return;
}
int mid = l + r >> 1;
if (L <= mid) update (now << 1, l, mid, L, R, x);
if (R >= mid + 1) update (now << 1 | 1, mid + 1, r, L, R, x);
pushup (now);
}
void updatea (int now, int l, int r, int L, int R, int x) {
pushdown (now, l, r);
if (l == r) {
ta[now] += x * (r - l + 1);
tgo[now] += x * tb[now];
lzya[now] += x;
return;
}
int mid = l + r >> 1;
if (L <= mid) updatea (now << 1, l, mid, L, R, x);
if (R >= mid + 1) updatea (now << 1 | 1, mid + 1, r, L, R, x);
pushup (now);
}
void updateb (int now, int l, int r, int L, int R, int x) {
pushdown (now, l, r);
if (l == r) {
tb[now] += x * (r - l + 1);
tgo[now] += x * ta[now];
lzyb[now] += x;
return;
}
int mid = l + r >> 1;
if (L <= mid) updateb (now << 1, l, mid, L, R, x);
if (R >= mid + 1) updateb (now << 1 | 1, mid + 1, r, L, R, x);
pushup (now);
}
int query (int now, int l, int r, int L, int R) {
pushdown (now, l, r);
if (l == r) return tv[now];
int mid = l + r >> 1, re = 0;
if (L <= mid) re += query (now << 1, l, mid, L, R);
if (R >= mid + 1) re += query (now << 1 | 1, mid + 1, r, L, R);
return re;
}
void go (int now, int l, int r, int L, int R, int x) {
pushdown (now, l, r);
if (l == r) {
lzyt[now] += x;
tv[now] += tgo[now] * x;
return;
}
int mid = l + r >> 1;
if (L <= mid) go (now << 1, l, mid, L, R, x);
if (R >= mid + 1) go (now << 1 | 1, mid + 1, r, L, R, x);
pushup (now);
}
int main () {
freopen ("drink.in","r",stdin);
freopen ("drink.out","w",stdout);
cin >> n >> m;
for (int i = 1; i<= n; ++ i) cin >> v[i] >>a[i] >> b[i];
build (1, 1, n);
// cout << tgo[1] << "\n";
int op, t, l, r, x, las = 0;
for (int i = 1; i <= m; ++ i) {
cin >> op >> t;
go (1, 1, n, 1, n, t - las);
// cout << tv[1] << " " << tgo[1] << "\n";
// for (int j = 1; j <= n; ++ j) {
// cout << query (1, 1, n, j, j) << " ";
// } puts ("|");
if (op == 1) {
cin >> l >> r;
cout << query (1, 1, n, l, r) << "\n";
}
if (op == 2) {
cin >> l >> r >> x;
updatea (1, 1, n, l, r, x);
}
if (op == 3) {
cin >> l >> r >> x;
updateb (1, 1, n, l, r, x);
}
if (op == 4) {
cin >> l >> r >> x;
update (1, 1, n, l, r, x);
}
las = t;
}
}
/*
5 5
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
2 1 1 3 2
1 3 2 3
3 4 1 4 -3
4 5 1 3 -5
1 6 1 5
*/
最后實在是調不出來了,干脆,單點修改單點查詢吧,成績出來了,測了一下,竟然沒 TLE 的有七個點,就是沒取模,一分沒有。
2022.10.26
讀錯題了,相同的東西換了兩種方式跑了兩邊。
好粗心啊。
就是這兩個東西。
我以為不一樣呢,式子寫的那么麻煩#¥……%
要注意認真讀題了。
2022.10.25
今天用了 \(string\) ,正解的思路,跑不過暴力,好強啊…
以后少用 \(string\) 了。
2022.10.23
考了 \(rk3\) ,空間開大點就 \(rk1\) 。
T1 :
我是真沒想到我打的 \(20\) 分的代碼能跑 \(40\) 分……
T3 :
算着復雜度貌似只能跑 \(40\) 分的。但是其實能跑到 \(60\) 分。
大意了。
總結一下就是,只要算好了空間,可以開大點,給程序多點機會多跑幾個點。真的就有時候與想的不同,排除復雜度算錯的原因,可能有數據水之類的情況發生。所以開大空間。
2022.9.25
下午打了 luogu 的 NOIP 模擬賽,然后幾個二臂錯誤沒了 175 pts,心痛/(ㄒoㄒ)/~~
T1:
然后掛了100 pts
T2:
沒認真讀題,空間小了一半,-75pts
然后 T3 給了個樣例分,然后我就拿了個樣例分。
總分:10 pts,預計分:185 pts
rank 3 沒了。
跳樓了,
2022.4.20
\(nyy\) 和 \(szt\) 出的模擬賽,感覺題目好有質量呀!!
所以考爆了。。
與往常不一樣,這次注意到要把數組開大點,不過開的有點過大了。。
就是這個題!!讓我打的主席樹跟暴力一個分,跟暴力一個分也就算了,蒟蒻的我數組開大了全 \(MLE\) 了 \(o(╥﹏╥)o\)
一開始打完了主席樹,調着調着大樣例,發現跑了一會不動彈了,,我就以為是數組開小了的事兒,於是傻不拉幾的把原本開的正好的數組改成了五六個 \(1e7\) 的數組。。然后繼續調,還是沒過,但是后來忘了把數組開了那么大了,也沒惜管,然后就超空間了。。
所以以后一定不要把開的過大或者過小了。
放一下原本的代碼,給個警醒。。
/**
* author: zcxxxxx
* creater: 2022.3.30
**/
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int A = 1e2 + 7;
const int B = 1e3 + 7;
const int C = 1e4 + 7;
const int D = 1e5 + 7;
const int E = 1e6 + 7;
const int INF = 1e18;
const int mod = 1e9 + 7;
inline int read() {
int 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 * 10 + c - '0', c = getchar();
return x * f;
}
int n, m, cnt, tot;
struct node {
int l, r, val, siz;
}t[E * 10];
int a[E * 10], b[E * 10], c[E * 10], d[E * 10];
int root[E * 10];
inline void work() {
sort(b + 1, b + 1 + n);
tot = unique(b + 1, b + 1 + n) - b - 1;
for(int i = 1; i <= n; ++ i) {
a[i] = lower_bound(b + 1, b + tot + 1, a[i]) - b;
d[a[i]] = c[i];
}
}
inline void build(int &now, int l, int r) {
now = ++ cnt;
if(l == r) {
t[now].val = d[l];
return;
}
int mid = l + r >> 1;
build(t[now].l, l, mid);
build(t[now].r, mid + 1, r);
}
inline void insert(int las, int &now, int l, int r, int x) {
now = ++ cnt;
t[now] = t[las];
t[now].siz ++;
if(l == r) {
return;
}
int mid = l + r >> 1;
if(x <= mid) insert(t[las].l, t[now].l, l, mid, x);
else insert(t[las].r, t[now].r, mid + 1, r, x);
}
int last, mn;
inline void query(int las, int now, int l, int r) {
if(!t[now].siz) return;
if(mn == 0) return;
if(l == r) {
if(t[now].siz > 1) mn = min(mn, 0ll);
else mn = min(mn, abs(t[now].val - last)), last = t[now].val;
return;
}
int mid = l + r >> 1;
int sl = t[t[now].l].siz - t[t[las].l].siz;
int sr = t[t[now].r].siz - t[t[las].r].siz;
if(sl) query(t[las].l, t[now].l, l, mid);
if(sr) query(t[las].r, t[now].r, mid + 1, r);
}
signed main() {
n = read();
for(register int i = 1; i <= n; ++ i) {
a[i] = b[i] = c[i] = read();
}
work();
build(root[0], 1, tot);
for(register int i = 1; i <= n; ++ i) {
insert(root[i - 1], root[i], 1, tot, a[i]);
}
m = read();
for(register int l, r, i = 1; i <= m; ++ i) {
l = read(), r = read();
mn = INF, last = -INF;
query(root[l - 1], root[r], 1, tot);
printf("%lld\n", mn);
}
return 0;
}
2022.2.27
又考試,從中午起來就感覺不對勁,身體軟綿綿的……
果然,下午又倒數。。。
竟然把橙題黃題都做錯了,第三題大暴力還沒打出來(;へ:)
做的是2015年的day1,做過的人都知道,除了T3都很水……
T1 是一道小模擬,雖然小吧,但是我好像是因為太困了,整整調了一節課 \(QAQ\),最后發現讀錯題了,“右上”讀成“左上”了……
T2 一看就是個找最小環,我直接激動地把 \(tarjan\) 就打上了呀,感覺很對。
最后一交,\(T1\) \(T2\) 都只有 \(50\),看了一下代碼,\(T1\) 數組開小了……
做題的時候迷迷糊糊的看了一眼數據范圍,然后打上了const int A = 47
就完了 (ノД`)
應該開 \(n ^ 2\) 的
\(T2\) 我的 \(tarjan\) 函數里初始化low[u] = dfn[u] = u
就很無語……
我怎么這么沒狀態,有大佬來指點一下該怎么避免嗎( Ĭ ^ Ĭ )
2022.2.13
寒假集訓結束前,舉行了一次模擬賽。。
然后……考了倒一
主要問題出在 T1 上,本來不算T1,T2T3 合起來能考第二來,然后 \(T1\) 爆了……,為什么呢,請觀摩如下兩份代碼:
/*
Worker:zcxxxxx
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100 + 7;
const int INF = 0x7fffffff;
inline int read() {
int 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 * 10 + c - '0', c = getchar();
return x * f;
}
int n;
string s;
int num[maxn];
int base = 233333;
int main() {
n = read();
for(int i = 1; i <= n; i++) {
cin >> s;
int len = s.size();
for(int j = 0; j < len; j++) {
num[j + 1] = s[j] - 'a' + 1;
num[j + 1] *= base;
}
for(int j = 1; j < len; j++) num[j] = (num[j] + num[len]) % 26 + 97, cout << (char)num[j];
}
return 0;
}
and
/*
Worker:zcxxxxx
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100 + 7;
const int INF = 0x7fffffff;
inline int read() {
int 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 * 10 + c - '0', c = getchar();
return x * f;
}
int n;
string s;
int num[maxn];
int base = 233333;
int main() {
n = read();
for(int i = 1; i <= n; i++) {
cin >> s;
int len = s.size();
for(int j = 0; j < len; j++) {
num[j + 1] = s[j] - 'a' + 1;
num[j + 1] *= base;
}
for(int j = 1; j < len; j++) num[j] = (num[j] + num[len]) % 26 + 97, cout << (char)num[j];
cout << "\n";
}
return 0;
}
一看好像沒啥區別,當我上午考完抑郁了一中午后,回到機房,打開測試點准備調代碼時,發現輸出和輸入混到一行了……
才發現原來是沒輸出換行,直接瘋掉。
最后幸虧有 \(npy\) ,才緩下來
直接少了 \(100\) 分啊,以后一定要檢查清楚嗚嗚嗚o(╥﹏╥)o