大概是相对来讲补的比较全的一场了。。。
(这个链接只是为了自己方便找,页面设置权限了,不要尝试访问)
(建议您从上方链接进入我的个人网站查看此 Blog,在 Luogu 中图片会被墙掉,部分 Markdown 也会失效)
排列
原题 LG-P7972 [KSN2021] Self Permutation
大概就是想到了一些性质(不过没用),想到了一些 DP 状态(然后没转移出来),总之最后的最后推了一个来小时,啥也没推出来,只能想到十分 nt 的
对于正整数序列
能依稀感觉有点像莫队但是依然不会,然后也没想到值域分块,最后糊了个暴力上去,
xxxxxxxxxx80123
4using namespace std;5
6mt19937 rnd(random_device{}());7int rndd(int l, int r){return rnd() % (r - l + 1) + l;}8bool rnddd(int x){return rndd(1, 100) <= x;}9
10111213
14typedef long long ll;15typedef unsigned long long unll;16typedef unsigned int uint;17typedef long double ld;18
19template < typename T = int >20T read(void);21
22int N, M;23int a[110000];24// bool vis[110000];25bitset < 101000 > vis;26// int buc100[1100][110000];27// vector < int > arr;28int main(){29 freopen("interval.in", "r", stdin);30 freopen("interval.out", "w", stdout);31 N = read(), M = read();32 for(int i = 1; i <= N; ++i)a[i] = read();33 // sort(arr.begin(), arr.end());34 // for(int i = 1; i <= N; ++i)a[i] = distance(arr.begin(), lower_bound(arr.begin(), arr.end(), a[i])) + 1;35 // for()36 if(M <= 1000){37 while(M--){38 int l = read(), r = read(), x = read(), y = read();39 int ans1(0), ans2(0);40 vis.reset();41 for(int i = l; i <= r; ++i){42 if(x <= a[i] && a[i] <= y){43 ++ans1;44 if(!vis[a[i]])vis.set(a[i]), ++ans2;45 }46 }47 printf("%d %d\n", ans1, ans2);48 }49 return 0;50 }51 if(N <= 1000){52 while(M--){53 int l = read(), r = read(), x = read(), y = read();54 int ans1(0);55 vector < int > tmp;56 for(int i = l; i <= r; ++i)57 if(x <= a[i] && a[i] <= y)++ans1, tmp.push_back(a[i]);58 auto endpos = unique(tmp.begin(), tmp.end());59 printf("%d %d\n", ans1, (int)distance(tmp.begin(), endpos));60 }61 return 0;62 }63
64 return 0;65}66
67template < typename T >68T read(void){69 T ret(0);70 short flag(1);71 char c = getchar();72 while(!isdigit(c) && c != '-')c = getchar();73 if(c == '-')flag = -1, c = getchar();74 while(isdigit(c)){75 ret *= 10;76 ret += int(c - '0');77 c = getchar();78 }ret *= flag;79 return ret;80}构造一棵有
原题 AT5140 [AGC035C] Skolem XOR Tree
阴间构造,只推出来了 puts("No") 也能过。
总之最后手动构造的 No 过了,成为了本场所有题里唯一的
xxxxxxxxxx95123
4using namespace std;5
6mt19937 rnd(random_device{}());7int rndd(int l, int r){return rnd() % (r - l + 1) + l;}8bool rnddd(int x){return rndd(1, 100) <= x;}9
10111213
14typedef long long ll;15typedef unsigned long long unll;16typedef unsigned int uint;17typedef long double ld;18
19template < typename T = int >20T read(void);21
22bool is2k[110000];23
24int main(){25 freopen("xortree.in", "r", stdin);26 freopen("xortree.out", "w", stdout);27 int N = read();28 int cur(1);29 while(cur <= 101000)is2k[cur] = true, cur <<= 1;30 if(is2k[N])printf("No\n"), exit(0);31 switch(N){32 // case 1:{33 // printf("No\n");34 // break;35 // }36 // case 2:{37 // printf("No\n");38 // break;39 // }40 case 3:{41 printf("Yes\n1 2\n2 3\n3 4\n4 5\n5 6\n");42 break;43 }44 // case 4:{45 // printf("");46 // break;47 // }48 case 5:{49 printf("Yes\n4 5\n5 1\n1 9\n9 10\n4 6\n6 8\n8 7\n6 2\n2 3\n");50 break;51 }52 case 6:{53 printf("Yes\n4 5\n5 1\n1 10\n4 7\n7 9\n9 8\n7 2\n2 3\n7 11\n10 6\n9 12\n");54 break;55 }56 case 7:{57 printf("Yes\n4 5\n5 1\n1 11\n4 8\n8 10\n10 9\n8 2\n2 3\n8 12\n11 6\n10 13\n12 14\n10 7\n");58 break;59 }60 // case 8:{61 // printf("");62 // break;63 // }64 case 9:{65 printf("10 8\n8 9\n10 18\n18 17\n10 5\n10 13\n13 15\n5 4\n4 1\n1 14\n1 2\n1 12\n14 7\n2 3\n12 11\n12 6\n12 16\n");66 break;67 }68 case 10:{69 printf("10 8\n8 9\n8 11\n11 19\n19 18\n11 5\n11 14\n5 4\n14 16\n4 1\n1 13\n1 2\n1 15\n15 7\n2 3\n3 12\n3 6\n3 17\n12 20\n");70 break;71 }72 default:{73 puts("No");74 break;75 }76 }77
78 79 return 0;80}81
82template < typename T >83T read(void){84 T ret(0);85 short flag(1);86 char c = getchar();87 while(!isdigit(c) && c != '-')c = getchar();88 if(c == '-')flag = -1, c = getchar();89 while(isdigit(c)){90 ret *= 10;91 ret += int(c - '0');92 c = getchar();93 }ret *= flag;94 return ret;95}期望题,不会,不过实际上不是很难,不是不可做的题。
把每个点建立一个区间,左右分别是第一个比它小的数的位置向中心移动一位,用单调栈从左到右从右到左各自维护一遍,令
xxxxxxxxxx89123
45678910
11/******************************12abbr13
14******************************/15
16using namespace std;17using namespace __gnu_pbds;18
19mt19937 rnd(random_device{}());20int rndd(int l, int r){return rnd() % (r - l + 1) + l;}21bool rnddd(int x){return rndd(1, 100) <= x;}22
23typedef unsigned int uint;24typedef unsigned long long unll;25typedef long long ll;26typedef long double ld;27
282930
31template<typename T = int>32inline T read(void);33
34int N;35int a[MAXN];36int lft[MAXN], rht[MAXN];37ll dp[MAXN];38ll ans(0);39stack < int > cur;40
41class TreeArray{42 private:43 int lim;44 ll tr[MAXN];45 public:46 void set(int lim){this->lim = lim;}47 int lowbit(int x){return x & -x;}48 void add(int x, ll v){while(x <= lim)tr[x] = (tr[x] + v) % MOD, x += lowbit(x);}49 ll query(int x){ll ret(0); while(x)ret = (ret + tr[x]) % MOD, x -= lowbit(x); return ret;}50}tr;51
52int main(){53 N = read();tr.set(N);54 for(int i = 1; i <= N; ++i)a[i] = read();55 for(int i = 1; i <= N; ++i){56 while(!cur.empty() && a[cur.top()] > a[i])rht[cur.top()] = i - 1, cur.pop();57 cur.push(i);58 }while(!cur.empty())rht[cur.top()] = N, cur.pop();59 for(int i = N; i >= 1; --i){60 while(!cur.empty() && a[cur.top()] > a[i])lft[cur.top()] = i + 1, cur.pop();61 cur.push(i);62 }while(!cur.empty())lft[cur.top()] = 1, cur.pop();63 tr.add(1, 1);64 for(int i = 1; i <= N; ++i){65 dp[i] = (tr.query(N) - tr.query(lft[i] - 1) + MOD) % MOD;66 tr.add(rht[i], dp[i]);67 }68 int cmn(INT_MAX);69 for(int i = N; i >= 1; --i){cmn = min(cmn, a[i]); if(cmn == a[i])ans = (ans + dp[i]) % MOD;}70 printf("%lld\n", ans);71 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);72 return 0;73}74
75template<typename T>76inline T read(void){77 T ret(0);78 short flag(1);79 char c = getchar();80 while(c != '-' && !isdigit(c))c = getchar();81 if(c == '-')flag = -1, c = getchar();82 while(isdigit(c)){83 ret *= 10;84 ret += int(c - '0');85 c = getchar();86 }87 ret *= flag;88 return ret;89}说实话这题确实不难,不过以前好像几乎没写过莫队,也没怎么写过值域分块,考场上是在是没想出来。
通过莫队维护区间
确实是没啥可说的。
xxxxxxxxxx126123
45678910
11/******************************12abbr13
14******************************/15
16using namespace std;17using namespace __gnu_pbds;18
19mt19937 rnd(random_device{}());20int rndd(int l, int r){return rnd() % (r - l + 1) + l;}21bool rnddd(int x){return rndd(1, 100) <= x;}22
23typedef unsigned int uint;24typedef unsigned long long unll;25typedef long long ll;26typedef long double ld;27
282930
31template<typename T = int>32inline T read(void);33
34int N, M;35int B;36int maxV(-1);37int blk[MAXN], blkv[MAXN];38int a[MAXN];39int sum_pos[MAXN];40int sum_blk[MAXN], sum_blk_exist[MAXN];41pair < int, int > ans[MAXN];42
43struct Query{44 int l, r;45 int a, b;46 int idx;47 friend const bool operator < (const Query x, const Query y){48 if(blk[x.l] != blk[y.l])return x.l < y.l;49 return blk[x.l] & 1 ? x.r < y.r : x.r > y.r;50 }51};52vector < Query > Q;53pair < int, int > QueryBlk(int l, int r){54 if(l > maxV)return {0, 0};55 r = min(r, maxV);56 int bl = blkv[l], br = blkv[r];57 int ret1(0), ret2(0);58 if(bl == br){59 for(int i = l; i <= r; ++i)ret1 += sum_pos[i], ret2 += (bool)sum_pos[i];60 return {ret1, ret2};61 }62 if(blkv[l - 1] == bl){63 for(int i = l; blkv[i] == bl && i <= maxV; ++i)64 ret1 += sum_pos[i], ret2 += (bool)sum_pos[i];65 ++bl;66 }67 if(blkv[r + 1] == br){68 for(int i = r; blkv[i] == br && i >= 1; --i)69 ret1 += sum_pos[i], ret2 += (bool)sum_pos[i];70 --br;71 }72 for(int i = bl; i <= br; ++i)73 ret1 += sum_blk[i], ret2 += sum_blk_exist[i];74 return {ret1, ret2};75}76void add(int x){77 ++sum_blk[blkv[x]];78 if(++sum_pos[x] == 1)++sum_blk_exist[blkv[x]];79}80void del(int x){81 --sum_blk[blkv[x]];82 if(--sum_pos[x] == 0)--sum_blk_exist[blkv[x]];83}84int main(){85 N = read(), M = read();86 B = (double)N / sqrt(M) + 1;87 for(int i = 1; i <= N; ++i)88 a[i] = read(), blk[i] = i / B + 1, maxV = max(maxV, a[i]);89 B = sqrt(maxV) + 1;90 for(int i = 1; i <= maxV; ++i)91 blkv[i] = i / B + 1;92 for(int i = 1; i <= M; ++i){93 int l = read(), r = read(), a = read(), b = read();94 Q.emplace_back(Query{l, r, a, b, i});95 }sort(Q.begin(), Q.end());96 int gl(0), gr(0);97 for(auto ask : Q){98 while(gl > ask.l)add(a[--gl]);99 while(gr < ask.r)add(a[++gr]);100 while(gl < ask.l)del(a[gl++]);101 while(gr > ask.r)del(a[gr--]);102 ans[ask.idx] = QueryBlk(ask.a, ask.b);103 }104 for(int i = 1; i <= M; ++i)printf("%d %d\n", ans[i].first, ans[i].second);105
106 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);107 return 0;108}109
110
111
112template<typename T>113inline T read(void){114 T ret(0);115 short flag(1);116 char c = getchar();117 while(c != '-' && !isdigit(c))c = getchar();118 if(c == '-')flag = -1, c = getchar();119 while(isdigit(c)){120 ret *= 10;121 ret += int(c - '0');122 c = getchar();123 }124 ret *= flag;125 return ret;126}确实算是一道很神奇的构造。
首先显然若
考虑到对于
然后若
xxxxxxxxxx67123
45678910
11/******************************12abbr13
14******************************/15
16using namespace std;17using namespace __gnu_pbds;18
19mt19937 rnd(random_device{}());20int rndd(int l, int r){return rnd() % (r - l + 1) + l;}21bool rnddd(int x){return rndd(1, 100) <= x;}22
23typedef unsigned int uint;24typedef unsigned long long unll;25typedef long long ll;26typedef long double ld;27
28template<typename T = int>29inline T read(void);30
31int lowbit(int x){return x & -x;}32
33int main(){34 int N = read();35 if(lowbit(N) == N)puts("No"), exit(0);36 puts("Yes");37 for(int i = 2; i <= N - 1; i += 2){38 printf("%d %d\n", 1, i);39 printf("%d %d\n", i, i + 1);40 printf("%d %d\n", 1, i + 1 + N);41 printf("%d %d\n", i + 1 + N, i + N);42 }43 printf("%d %d\n", 3, 1 + N);44 if(!(N & 1)){45 printf("%d %d\n", N, lowbit(N) + 1 + N);46 printf("%d %d\n", N - lowbit(N), N + N);47 }48
49 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);50 return 0;51}52
53template<typename T>54inline T read(void){55 T ret(0);56 short flag(1);57 char c = getchar();58 while(c != '-' && !isdigit(c))c = getchar();59 if(c == '-')flag = -1, c = getchar();60 while(isdigit(c)){61 ret *= 10;62 ret += int(c - '0');63 c = getchar();64 }65 ret *= flag;66 return ret;67}咕咕咕,不过这题还不错,加到题单里了,laterrrrrrrrrrrr 可以做一做。
update-2022_10_14 初稿