2022.10.24

2022.10.24

生日快乐!!!嘿嘿嘿。

稍微写一哈。

早上做核酸,聂老师又发火了,因为我们不看红绿灯。

好吧,这确实是我们的错。

虽然但是,更愿意被老吕训,而不愿意听聂老师巴巴。

昨天晚上的 DEV 不知道怎么了,没法编译,重下了好几遍都不行,在 gym 同学的帮助下修好了 DEV。感谢gym同学,好人 AK CSP, NOIP!!!

于是留了题今天改。找理由ing。

哦! 还要感谢 wzq 同学!

T3

拿了 \(n = 1\) 的分。

爆搜行走路线?孩子节点数不超过 2 ?树的高度不超过 3 ? 贪心?

不会耶!

/*
work by:Ariel_
*/
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 1e6 + 7;
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, w[MAXN], f[MAXN];
struct edge{int v, nxt;}e[MAXN];
int head[MAXN], E;
void add_edge(int u, int v) {
  e[++E] = (edge) {v, head[u]};
  head[u] = E;
}
struct node{int A, B;}c[MAXN];
bool cmp(node x, node y) {
  return (x.A - x.B) > (y.A - y.B);
}
void dfs(int x) {
  for (int i = head[x], v; i; i = e[i].nxt) {
       v = e[i].v, dfs(v);
  }
  int tot = 0;
  for (int i = head[x]; i; i = e[i].nxt) {
      int v = e[i].v;
    c[++tot].A = f[v], c[tot].B = w[v]; 
  }
  sort(c + 1, c + tot + 1, cmp);
  int res = 0;
  for (int i = 1; i <= tot; i++) {
      if(res >= c[i].A) res -= c[i].B;    
    else {
      f[x] += c[i].A - res;
      res = c[i].A - c[i].B;
    }
  }
  f[x] += max(0ll, w[x] - res);
}
signed main(){
  //freopen("ttt.in", "r", stdin);
  //freopen("ttt.out", "w", stdout);
  n = read();
  for (int i = 2, x; i <= n; i++) {
       x = read();
       add_edge(x, i);
  }
  for (int i = 1; i <= n; i++) w[i] = read();
  dfs(1); 
  for (int i = 1; i <= n; i++) cout<<f[i]<<" ";
  puts("");
  return 0;
}

T4

拿了爆搜的分。

无了。

转眼10:30了。

喷水装置
/*
Date:2022.10.24
Source:LOJ
knowledge:贪心 没认真写 
*/
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#define orz cout << "AK IOI" << "\n";

using namespace std;
const int maxn = 15010;

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 T, n, L, W;
double a, R;
struct node{
    double l, r;
}e[maxn << 1];
bool cmp(node a, node b)
{
    return a.l < b.l;
}
int main()
{
    //freopen(".in", "r", stdin);  
    //freopen(".out", "w", stdout);
    T = read();
    while(T--)
    {
        int cnt = 0;
        n = read(); L = read(); W = read();
        for(int i = 1; i <= n; i++)
        {
            scanf("%lf%lf", &a, &R);
            if(2 * R <= W) continue;//不能完全覆盖宽,跳过 
            cnt++;
            e[cnt].l = a - sqrt(R * R - W * W / 4.0);
            e[cnt].r = a + sqrt(R * R - W * W / 4.0);
        } 
        sort(e + 1, e + cnt + 1, cmp);
        double now = 0;
        int ans = 0, flag = 0, j = 1;
        while(now < L)
        {
            ans++;
            double s = now;
            for( ; e[j].l <= s && j <= n; j++)
                if(now < e[j].r) now = e[j].r;
            if(now == s && s < L)
            {
                printf("-1\n");
                flag = 1;
                break;
            }
        }
        if(flag == 0) printf("%d\n",ans);
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
加工生产调度
/*
Date:2022.10.24
Source:LOJ
knowledge:贪心 依旧没认真写 
*/
#include <cstdio>
#include <iostream>
#define orz cout << "AK IOI" << "\n";

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;
}
int n, a[maxn], b[maxn], m[maxn]; 
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++) b[i] = read();
    for(int i = 1; i <= n; i++) m[i] = Min(a[i], b[i]), s[i] = i;

    for(int i = 1; i <= n - 1; i++)
        for(int j = i + 1; j <= n; j++)
               if(m[i] > m[j]) swap(m[i], m[j]), swap(s[i], s[j]);
    int k = 0, t = n + 1;
    for(int i = 1; i <= n; i++)
       if(m[i] == a[s[i]]) k++, ans[k] = s[i];
       else t--, ans[t] = s[i]; 
    k = 0; t = 0;
    for(int i = 1; i <= n; i++)
    {
        k += a[ans[i]];
        if(t < k) t = k;
        t += b[ans[i]];
    } 
    printf("%d\n",t);
    for(int i = 1; i <= n; i++) printf("%d ",ans[i]);
    printf("\n");
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}

稍微总结一哈贪心。

对于个人而言,感觉贪心的题目多是,有很多个任务相互重叠,相互制约,求最优的解决的办法。

解法主要在于排序,按各种奇怪的顺序排序。

发现贪心的方法在于手摸样例?在于直觉?

很好,我没有直觉。

所以如果感到题目瞻前顾后的话,就考虑一下贪心,猜个结论,按各种奇怪的顺序拍拍序,去过大样例吧。

关于考试……

感觉一开始异常的浮躁。

导致一开始的读题没有读出应有的效果,而且浪费了不少时间。

T4 的题面真的很长,但一般这种长题面,都蕴含着无脑暴力分(例如,贪吃蛇),所以我耐着性子读了几遍,但是除了\(n = 0\) 的情况,什么都没写出来,在2:40 离开 T4 去做 T3。

T3 有些想法,但是真的很浮躁,脑子很乱,胡乱写了写去看 T1。

T1感觉可做,移了移项,胡乱搞了一阵子,也出现了乱七八糟的错误,发现应该枚举 \(y\)

然后跟暴力拍,因为是暴力,所以跑的特别慢,慢到怀疑人生。

好不容易跑出来了,还是错的。

我很慌,调了一阵子,最后发现暴力写错了!!!

这个时候考试过了多长时间已经忘了。

但是 T1 之后人确实不浮躁了,这是叫进入状态了?

但是一切都太晚了

T2 写了暴力,还要调。

T3 写了线段树,还要调,一直调到最后一分钟。最后130 行的线段树得了 15 分。

感觉 有关T3 的那点想法可以在思考一下,多花一点时间,虽然可能实现不了。

T4 也应该再多花一点时间的。

T1

/*
Date:
Source:
knowledge:不能枚举x,枚举y。 
拍不过去,发现暴力写错了! 
*/
#include <cstdio>
#include <iostream>
#define orz cout << "AK IOI" << "\n";
#define int unsigned long long 

using namespace std;

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 T, a, b, c, d, ans;
signed main()
{
	//freopen("equation.in", "r", stdin);
	//freopen("equation.out", "w", stdout);
	T = read();
	while(T--)
	{
		ans = 0;
		a = read(), b = read(), c = read(), d = read();
		for(int i = 1; i <= 1e7; i++)
		{
			int A = a * c * i, B = d * c - b * i;
			if(A < B || B == 0) continue;
			if((A % B) == 0) ans++;
		}
		print(ans), puts("");
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
/*
1
6 7 9 10
*/

T3

这颗线段树必须露一下脸。

/*
Date:
Source:
knowledge: 很像数据结构啊 
有点想法 写线段树到最后一秒 
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#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 = 100010;

int read()
{
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
void print(int X)
{
	if(X < 0) X = ~(X - 1), putchar('-');
	if(X > 9) print(X / 10);
	putchar(X % 10 ^ '0');
}
int Max(int a, int b){
	return a > b ? a : b;
}
int Min(int a, int b){
	return a < b ? a : b;
}
int n, m, q, a[maxn], ans;
int getnum(char x)
{
	if(x == '0') return 0;
	if(x == '1') return 1;
	if(x == '?') return -0x3f3f3f3f;
} 
struct tree{
	int l, r, sum, num;
}t[maxn << 2];
void push_up(int rt)
{
	t[rt].sum = t[ls].sum + t[rs].sum;
	t[rt].num = t[ls].num + t[rs].num;
}
void build(int rt, int l, int r)
{
	t[rt].l = l, t[rt].r = r;
	if(l == r) 
	{
		t[rt].sum = a[l]; 
		if(a[l] = -0x3f3f3f3f) t[rt].num = 1;
		return ;
	}
	int mid = (l + r) >> 1;
	build(ls, l, mid), build(rs, mid + 1, r);
	push_up(rt);
}
void updata(int rt, int k, int val)
{
	if(t[rt].l == t[rt].r && t[rt].l == k)
	{
	 	t[r].sum = val;
		if(val == -0x3f3f3f3f) t[rt].num = 1;
		return ; 	
	}
	int mid = (t[rt].l + t[rt].r) >> 1;
	if(k <= mid) updata(ls, k, val);
	else updata(rs, k, val);
	push_up(rt);
}
int query1(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, res = 0;
	if(l <= mid) res += query1(ls, l, r);
	if(r > mid) res += query1(rs, l, r);
	return res;  
}
int query2(int rt, int l, int r)
{
	if(t[rt].l >= l && t[rt].r <= r) return t[rt].num;
	int mid = (t[rt].l + t[rt].r) >> 1, res = 0;
	if(l <= mid) res += query2(ls, l, r);
	if(r > mid) res += query2(rs, l, r);
	return res;  
}
signed main()
{
	freopen("string.in", "r", stdin);
	freopen("string.out", "w", stdout);
	n = read(), m = read(), q = read();
	for(int i = 1; i <= m; i++) 
	{
		char s; 
		cin >> s;
		a[i] = getnum(s);
	}
	build(1, 1, m);
	for(int i = 1; i <= q; i++)
	{
		int opt = read();
		if(opt == 1)
		{
			int x = read();
			char s;
			cin >> s;
			int aa = getnum(s);
			updata(1, x, aa); 
		}
		else 
		{
			int x = read(), y = read();
			int f1 = query1(1, x, y), f2 = query2(1, x, y);
			if(f1 == (y - x + 1) || f1 == 0) ans = ans ^ 1;
			else if(f1 > 0) ans = ans ^ 0;
			else if((f1 + f2 * -0x3f3f3f3f != (y - x + 1 - f2)) || ((f1 + f2 * -0x3f3f3f3f != 0))) ans = ans ^ 0;
			else ans = ans ^ 1;
		}
	}
	cout << ans;
	fclose(stdin);
	fclose(stdout);
	return 0;
}
posted @ 2022-10-24 10:05  _程门立雪  阅读(29)  评论(0编辑  收藏  举报