2022.10.23

2022.10.23

稍微写一哈。

现在好多人叫我学姐呀!

有点美滋滋的。虽然教不了他们什么了。可以考试帮大家垫垫底。

哦!这 8 天的缘分!

上午效率怪低的。

贪心贪不明白,搜索搜不明白。

/*
Date:2022.10.23
Source:LOJ
knowledge:贪心 按结束时间排序,每个区间的树都先区间的右侧种,以达到最大的重合 
至于为什么按结束时间排序,手摸样例感性理解一下,大概是会有更多的重复的空间。 
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#define orz cout << "AK IOI" << "\n";

using namespace std;
const int maxn = 3e4 + 10;

inline int read()
{
    int x = 0, f = 1;  char ch = getchar();
    while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();}
    while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    return x * f;
}
inline void print(int X)
{
    if(X < 0) X = ~(X - 1), putchar('-');
    if(X > 9) print(X / 10);
    putchar(X % 10 ^ '0');
    return ;
}
inline int Max(int a, int b){
    return a > b ? a : b;
}
inline int Min(int a, int b){
    return a < b ? a : b;
}
int n, m, ans; 
bool vis[maxn];
struct node{
    int b, e, t;
}a[maxn];
bool cmp(node a, node b)
{
    return a.e < b.e;
}
int main()
{
    //freopen(".in", "r", stdin);     
    //freopen(".out", "w", stdout);
    n = read(), m = read();
    for(int i = 1; i <= m; i++) 
        a[i].b = read(), a[i].e = read(), a[i].t = read();
    sort(a + 1, a + m + 1, cmp);
    for(int i = 1; i <= m; i++)
    {
        int k = 0;
        for(int j = a[i].b; j <= a[i].e; j++) if(vis[j]) k++;
        if(k >= a[i].t) continue;
        for(int j = a[i].e; j >= a[i].b; j--)
        {
            if(!vis[j]) vis[j] = 1, k++, ans++;
            if(k >= a[i].t) break;
        }
    } 
    print(ans);
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
/*
Date:2022.10.22
Source:LUOGU 4145 
knowledge:永远猜不到出题人在想什么
注意开平方,sqrt(1) = 1, 最大的数开次平方就会到1,所以要记录区间最大值,若为1,则不用进行操作 
进行单点修改 
*/
#include <cstdio>
#include <cmath>
#include <iostream>
#define orz cout << "AK IOI" << "\n";
#define int long long
#define ls rt << 1
#define rs rt << 1 | 1

using namespace std;
const int maxn = 1e5 + 10;
const int maxm = 2e5 + 10;

inline int read()
{
    int x = 0, f = 1;  char ch = getchar();
    while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();}
    while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    return x * f;
}
inline void print(int X)
{
    if(X < 0) X = ~(X - 1), putchar('-');
    if(X > 9) print(X / 10);
    putchar(X % 10 ^ '0');
    return ;
}
inline int Max(int a, int b){
    return a > b ? a : b;
}
inline int Min(int a, int b){
    return a < b ? a : b;
}
int n, m, a[maxn]; 
struct tree{
    int sum, l, r, maxx;
}t[maxn << 2];
void push_up(int rt)
{
    t[rt].sum = t[ls].sum + t[rs].sum;
    t[rt].maxx = Max(t[ls].maxx, t[rs].maxx);
}
void build(int rt, int l, int r)
{
    t[rt].l = l, t[rt].r = r;
    if(l == r) 
    {
        t[rt].sum = t[rt].maxx = a[l];
        return ;
    }
    int mid = l + r >> 1;
    build(ls, l, mid), build(rs, mid + 1, r);
    push_up(rt); 
}
int query(int rt, int l, int r)
{
    if(t[rt].l >= l && t[rt].r <= r) return t[rt].sum;
    int mid = (t[rt].l + t[rt].r) >> 1, ans = 0;
    if(l <= mid) ans += query(ls, l, r);
    if(r > mid) ans += query(rs, l, r);
    return ans;
}
void updata(int rt, int l, int r)
{
    if(t[rt].l == t[rt].r) 
    {
        t[rt].maxx = sqrt(t[rt].maxx);
        t[rt].sum = sqrt(t[rt].sum);
        return ;
    }
    int mid = (t[rt].l + t[rt].r) >> 1;
    if(l <= mid && t[ls].maxx > 1) updata(ls, l, r);
    if(r > mid && t[rs].maxx > 1) updata(rs, l, r);
    push_up(rt);
}
signed main()
{
    //freopen(".in", "r", stdin);
    //freopen(".out", "w", stdout);
    n = read();
    for(int i = 1; i <= n; i++) a[i] = read();
    m = read();
    build(1, 1, n);
    for(int i = 1; i <= m; i++)
    {
        int x = read(), l = read(), r = read();
        if(l > r) swap(l, r);
        if(x == 1) printf("%lld\n", query(1, l, r));
        else updata(1, l, r);
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}

关于考试……

代码能力严重下降,或者一直都没好过,30min 左右读题,然后 T4 暴力生写了一个小时,然后调的过程中发现自己写错了,然后又花了 30 min 写了 16 分的暴力。

然后 T3 30min, T4 30min, T1 不到 50 min,最后 10 min 整理了文件夹,然后开始喝茶。

总体感觉,能拿的无脑暴力分有了,还要拿经过思考后的分。

主要问题在于代码能力太菜了,留给自己思考的时间,发现规律的时间不多。虽然感觉也发现不了

T1

枚举 \(x\)\(y\) 判断合法的 \(z\) 的位置,倒序枚举 \(y\), 用 \(map\) 记录\([y + 1, n]\) 区间内每个数出现的次数,每次答案加上 \(gcd(a_x, a_y)\) 的个数, \(y\) 减小的时候将 \(a_y\) 入桶。

感觉应该想到的。

/*
Date:2022.10.23
Source: 模拟赛补题 
knowledge:
*/
#include <cstdio>
#include <iostream>
#include <map>
#define orz cout << "AK IOI" << "\n";

using namespace std;
const int maxn = 3010; 

inline int read()
{
    int x = 0, f = 1;  char ch = getchar();
    while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();}
    while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    return x * f;
}
inline void print(int X)
{
    if(X < 0) X = ~(X - 1), putchar('-');
    if(X > 9) print(X / 10);
    putchar(X % 10 ^ '0');
    return ;
}
inline int Max(int a, int b){
    return a > b ? a : b;
}
inline int Min(int a, int b){
    return a < b ? a : b;
}
int n, a[maxn];
long long ans;
map<int, int> mp;
int gcd(int a, int b){
    return b == 0 ? a : gcd(b, a % b);
}
int main()
{
    //freopen(".in", "r", stdin);
    //freopen(".out", "w", stdout);
    n = read();
    for(int i = 1; i <= n; i++) a[i] = read();
    for(int i = 1; i <= n; i++)
    {
        mp.clear();
        for(int j = n; j > i; --j)
        {
            ans += mp[gcd(a[i], a[j])]; 
            mp[a[j]]++;
        }
    }
    printf("%lld", ans);
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}

T2

拿了爆搜的 $30pts。

正解 \(DP\) + 二分。这个 \(dp\) 还是蛮简单的,就是很久没写了吧。找理由

这个题的分算是拿满了吧。

/*
Date:2022.10.24 
Source:模拟赛补题 
knowledge: 二分 + DP 
很好,二分怎么写来着?  
f[i]表示 以i结尾的符合条件的最长子序列的长度 
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#define orz cout << "AK IOI" << "\n";
#define int long long

using namespace std;
const int maxn = 1010;

inline int read()
{
	int x = 0, f = 1;  char ch = getchar();
	while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();}
	while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
inline void print(int X)
{
	if(X < 0) X = ~(X - 1), putchar('-');
	if(X > 9) print(X / 10);
	putchar(X % 10 ^ '0');
	return ;
}
inline int Max(int a, int b){
	return a > b ? a : b;
}
inline int Min(int a, int b){
	return a < b ? a : b;
}
inline int Abs(int a){
	return a > 0 ? a : -a;
}
int n, m, a[maxn], l, r = -1, ans, f[maxn]; 
bool check(int k)
{
	for(int i = 1; i <= n; i++) f[i] = 1;
	for(int i = 1; i <= n; i++) 
		for(int j = 1; j < i; j++)
			if(Abs(a[i] - a[j]) <= k) f[i] = max(f[i], f[j] + 1);
	for(int i = 1; i <= n; i++) if(f[i] >= m) return 1;
	return 0; 
} 
signed main()
{
	//freopen("cauchy7.in", "r", stdin); 
	//freopen(".out", "w", stdout);
    n = read(), m = read();
    for(int i = 1; i <= n; i++) a[i] = read(), r = Max(r, a[i]);
    while(l <= r)
    {
    	int mid = (l + r) >> 1;
    	if(check(mid)) ans = mid, r = mid - 1;
    	else l = mid + 1;
	}
	print(ans);
	//fclose(stdin);
	//fclose(stdout);
	return 0;
}

posted @ 2022-10-24 09:53  _程门立雪  阅读(21)  评论(0编辑  收藏  举报