首页 > 其他分享 >The 2024 CCPC National Invitational Contest (Northeast), The 18th Northeast Collegiate Programming C

The 2024 CCPC National Invitational Contest (Northeast), The 18th Northeast Collegiate Programming C

时间:2024-09-05 15:03:41浏览次数:14  
标签:std Invitational Northeast Contest int LL mid long operatorname

目录

写在前面

比赛地址:https://codeforces.com/gym/105173

以下按个人难度向排序。

就俩人刚开学处于唐氏状态于是开把省赛,呃呃然而还是唐多亏 dztlb 大神爆切两道计数还不算烂。

J

签到。

唉感觉读研究生好可怕感觉还不如直接去打工不想打了就跑路。

Code by dztlb:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int lim=1e18;
const int N=2e5+5;
inline int read(){
	int x=0,f=1; char s;
	while((s=getchar())<'0'||s>'9') if(s=='-') f=-1;
	while(s>='0'&&s<='9') x=(x*10)+(s^'0'),s=getchar();
	return x*f;
}
int T;
signed main(){
	puts("39.20");
	return 0;
}

D

签到,博弈,

实际诈骗题,手玩下发现后手获胜的情况根本不存在,于是直接 lose

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    int n;
    std::cin >> n;
    std::cout << "lose\n";
  }
  return 0;
}

A

签到,枚举。

乘方后再开方是无贡献的,则操作顺序一定是先一直开方再一直乘方。

于是直接枚举开方次数,再大力乘方直到第一个已经出现过的数或者大于上限 \(10^9\),则可以保证之后的乘方的值一定不会重复出现。

偷懒写个 map,总时间复杂度 \(O(\log x\log v)\) 级别。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const LL kInf = 1e9;
//=============================================================
LL ans;
std::map<LL, bool> yes;
//=============================================================
void check(int remain_, LL t_) {
  ++ ans;
  yes[t_] = 1;

  int flag = 0;
  while (remain_ && t_ <= kInf) {
    t_ = t_ * t_;
    if (yes.count(t_)) {
      flag = 1;
      break;
    }
    yes[t_] = 1;
    -- remain_;
    ++ ans;
  }
  if (!flag) ans += remain_;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  LL x, k; std::cin >> x >> k;
  if (x == 1) {
    std::cout << 1 << "\n";
    return 0;
  }

  ans = 1 + k;
  yes[x] = 1;

  for (int i = 1; i <= k; ++ i) {
    LL t = sqrt(x);
    if (t == 1) {
      ++ ans;
      break;
    }
    check(k - i, t);
    x = t;
  }
  std::cout << ans << "\n";
  return 0;
}
/*
9 10

5 2
*/

E

签到,数学,枚举。

设给定字符串中 1 的数量为 \(m\),记 \(\operatorname{cnt}\) 表示某个正整数中 1 的个数,则有下式成立:

\[(m + \operatorname{cnt}(B)) \bmod 2^k = B \]

把 \(\bmod 2^k\) 拆掉然后移项,则有:

\[m - c\times 2^k = B - \operatorname{cnt}(B) \]

此时等式左右两部分是独立的,于是考虑预处理右边,并枚举左边。因为 \(B - \operatorname{cnt}(B)\ge 0\),则 \(m \ge c\times 2^k\),可行的 \(c\) 的数量级为 \(O(m)\) 级别,于是可以考虑直接大力枚举 \(c\) 计算 \(m-c\times 2^k\),并检查对应的 \(B - \operatorname{cnt}(B)\) 的最小值即可。

总时间复杂度 \(O\left(2^k + \sum n\right)\) 级别。

妈的赛时没特判 0 挂了四发太唐乐。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e6 + 10;
//=============================================================
int n, k, m, all, ans;
std::string s;
int val[kN];
//=============================================================
int count(int x_) {
  int ret = 0;
  while (x_) {
    if (x_ & 1) ++ ret;
    x_ >>= 1;
  }
  return ret;
}
std::string get(int x_) {
  std::string t;
  for (int i = 1; i <= k; ++ i) {
    if (x_ & 1) t.push_back('1');
    else t.push_back('0');
    x_ >>= 1;
  }
  std::reverse(t.begin(), t.end());
  return t;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  for (int i = 0; i <= 2e6; ++ i) val[i] = -1;
  for (int i = 0; i <= 2e6; ++ i) {
    int c = count(i);
    if (val[i - c] == -1) val[i - c] = i;
  }
  
  int T; std::cin >> T;
  while (T --) {
    std::cin >> n >> k;
    std::cin >> s; s = "$" + s;
    m = 0, all = (1 << k), ans = kN;
    for (int i = 1; i <= n; ++ i) m += (s[i] == '1');

    for (int i = 0; i * all <= m; ++ i) {
      if (0 <= val[m - i * all] && val[m - i * all] < all) {
        ans = std::min(ans, val[m - i * all]);
      }
    }

    if (ans == kN) std::cout << "None\n";
    else std::cout << get(ans) << "\n";
  }
  return 0;
}
/*
1
2 1
0
*/

M

枚举,计算几何

实际大力枚举题。

发现房子的上下两部分实际上是独立的,仅需保证这两部分分别合法,且在天花板不同的两侧即可。判断直角使用点乘,判断点在直线的哪一侧使用叉乘即可。

于是考虑 \(O(n^3)\) 地枚举天花板和房顶并预处理对于每个天花板,两侧合法的屋顶数量有多少。然后再 \(O(n^3)\) 地枚举天花板和房子下部分矩形的另一个点,并计算第四个点检查是否存在,再直接检查天花板另一侧的屋顶数量即可。

发现仅比较距离和算点乘叉乘的符号因此可以全程用 LL。偷懒写个 map,总时间复杂度 \(O(n^3\log n)\) 级别。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
#define pr std::pair
#define mp std::make_pair
const int kN = 310;
//=============================================================
int n, x[kN], y[kN];
struct Point {
  LL x, y;
} a[kN];
std::map <pr <LL, LL>, bool> node;
int roof[kN][kN][2];
//=============================================================
LL distance2(LL x1_, LL y1_, LL x2_, LL y2_) {
  return 1ll * (x1_ - x2_) * (x1_ - x2_) + (y1_ - y2_) * (y1_ - y2_);
}
LL dotProduct(LL x1_, LL y1_, LL x2_, LL y2_) {
  return 1ll * x1_ * x2_ + y1_ * y2_;
}
LL crossProduct(LL x1_, LL y1_, LL x2_, LL y2_) {
  return 1ll * x1_ * y2_ - x2_ * y1_;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  std::cin >> n;
  for (int i = 1; i <= n; ++ i) {
    std::cin >> x[i] >> y[i];
    node[mp(x[i], y[i])] = 1;
  }
  for (int i = 1; i <= n; ++ i) {
    for (int j = i + 1; j <= n; ++ j) {
      for (int k = 1; k <= n; ++ k) {
        if (i == k || j == k) continue;
        if (distance2(x[i], y[i], x[k], y[k]) == 
            distance2(x[j], y[j], x[k], y[k])) {
          LL cp = crossProduct(x[j] - x[i], y[j] - y[i], x[k] - x[i], y[k] - y[i]);
          if (cp == 0) continue;
          ++ roof[i][j][cp > 0];
        }
      }
      // std::cout << i << " " << j << "   " << roof[i][j][0] << "-" << roof[i][j][1] << "\n";
    }
  }

  LL ans = 0;
  for (int i = 1; i <= n; ++ i) {
    for (int j = i + 1; j <= n; ++ j) {
      for (int k = 1; k <= n; ++ k) {
        if (i == k || j == k) continue;
        if (dotProduct(x[j] - x[i], y[j] - y[i], x[k] - x[i], y[k] - y[i]) != 0) continue;
        LL xl = x[k] + x[j] - x[i];
        LL yl = y[k] + y[j] - y[i];
        if (!node.count(mp(xl, yl))) continue;

        LL cp = crossProduct(x[j] - x[i], y[j] - y[i], x[k] - x[i], y[k] - y[i]);
        if (cp == 0) continue;
        ans += roof[i][j][(cp > 0) ^ 1];
      }
    }
  }
  std::cout << ans << "\n";
  return 0;
}

F

数论,搜索

实际大力题呃呃,妈的怎么这么多大力题

题目要求实际即下式:

\[p\times k^{\infin} \bmod q = 0 \]

即仅需保证:

  • \(q\) 中仅有 \(p, k\) 中的质因数。
  • \(q\) 中各质因数的次数不大于 \(p\times k^{\infin}\) 中对应质因数的次数。

因为 \(p\times k\) 的质因数至多只有不到 100 个,且有 \(q\le x\le 10^{14}\),由数学直觉可知实际上答案的数量级并不会很大,又发现给了 5s 的时限,于是考虑直接 DFS 大力枚举因数即可。可以保证一定仅会搜到有贡献的答案则复杂度并不会很高。

注意搜因数过程中可能爆 LL。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
#define i128 __int128
const int kN = 1e6;
//=============================================================
LL p, x, k, ans, prisz;
std::vector<LL> pri;
std::map<LL, int> cnt;
//=============================================================
void init() {
  LL temp = p;
  for (LL i = 2; i * i <= temp; ++ i) {
    if (temp % i != 0) continue;
    if (!cnt.count(i)) pri.push_back(i), cnt[i] = 0;
    while (temp % i == 0) temp /= i, cnt[i] = cnt[i] + 1;
  }
  if (temp != 1) {
    if (!cnt.count(temp)) pri.push_back(temp), cnt[temp] = 0;
    cnt[temp] = cnt[temp] + 1;
  }

  temp = k;
  for (LL i = 2; i * i <= temp; ++ i) {
    if (temp % i != 0) continue;
    if (!cnt.count(i)) pri.push_back(i);
    cnt[i] = kN;
    while (temp % i == 0) temp /= i;
  }
  if (temp != 1) {
    if (!cnt.count(temp)) pri.push_back(temp);
    cnt[temp] = kN;
  }
}
void dfs(int now_, i128 prod_) {
  if (prod_ > x) return ;
  if (now_ >= prisz) {
    ++ ans;
    // std::cout << prod_ << "\n";
    return ;
  }
  for (int i = 0, sz = cnt[pri[now_]]; i <= sz && prod_ <= x; ++ i) {
    dfs(now_ + 1, prod_);
    prod_ *= pri[now_];
  }
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  std::cin >> p >> x >> k;
  init();
  prisz = pri.size();
  // for (auto [a, b]: cnt) std::cout << a << " " << b << "\n";
  dfs(0, 1);
  std::cout << ans << "\n";
  return 0;
}

L

计数,栈,括号序列。

发现对于一个括号嵌套的形式,一定是从内到外操作的。则实际上规定了操作的一个拓扑序,操作间构成了一个有根树的结构,不同子树间的操作是独立的,它们在操作序列中的顺序任意;有祖先关系的节点间必须保证操作顺序。

于是考虑按照括号的包含关系建树。因为加括号是每次往括号序列的末端加的,考虑倒序枚举括号序列进行操作序列的构造,并考虑枚举到的括号可以被插入到操作序列的什么位置,即按照树的先序遍历的倒序进行构造。对于倒序枚举到的某个节点 \(i\):

  • 若为叶节点,则仅能插入到操作序列的开头,对答案贡献为 1;
  • 若不为叶节点,则可插入操作序列的任意位置,对答案贡献为 \(n-i+1\)。

贡献的乘积即为答案。

当然也可以直接考虑倒序枚举括号序列,根据组合意义进行推导,可以得到和上面的式子本质一样的做法。赛时 dztlb 大神就是这样直接倒着做就切了太牛逼了。

Code by dztlb:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int lim=1e18;
const int N=1e6+5;
const int mod=998244353;
inline int read(){
	int x=0,f=1; char s;
	while((s=getchar())<'0'||s>'9') if(s=='-') f=-1;
	while(s>='0'&&s<='9') x=(x*10)+(s^'0'),s=getchar();
	return x*f;
}
int n;
char s[N];
int st[N],top;
int a[N],tot;
int id[N];
signed main(){
	scanf("%s",s+1);
	n=strlen(s+1);
	top=1;
	st[1]=1;
	int cnt=0;
	for(int i=2;i<=n;++i){
		if(s[i]==')'){
			if(st[top]==i-1){
				++cnt;
				id[i]=cnt;
				--top;
			}else{
				id[i]=id[i-1];
				a[++tot]=id[i]-1;
				--top;
			}
		}else{
			st[++top]=i;
		}
	}
	int ans=1;
	cnt--;
	for(int i=tot;i>=1;--i){
		ans=ans*(cnt-a[i]+1+tot-i)%mod;
	}
	cout<<ans;
	return 0;
}
/*
((()())()())(())
(())()
(())()()()()()()()()()()() 
*/

I

计数,DP。

妈的 dztlb 大神最后爆切,可惜吃了 9 发呃呃唐。

显然考虑计数 DP。设当前填到了前缀 \(1\sim i\) 且令其合法的方案数为 \(f_i\)。由性质可保证所有前缀的最后 \(k\) 个数一定构成大小为 \(k\) 的排列,于是考虑枚举填到 \(i\) 时最后一步添加了多少数 \(j\) 使得 \([i-k+1, i]\) 也为排列。初始化 \(f_{k} = k!\)。

由于排列是不重复的,并不需要考虑之前的数的具体种类,仅需考虑其个数即可。于是记 \(g_{j}\) 表示在一个大小为 \(k\) 的排列后面添加 \(j\) 个数使得下列两条件成立的方案数:

  • 新数列区间 \([j + 1, j + k]\) 构成大小为 \(k\) 的排列;
  • 对于任意 \(1\le i\le j\),\([i, i + k - 1]\) 不是排列,即保证添加 \(j\) 个数后最后一个长度为 \(k\) 的区间一定是好的,从而保证上述对 \(f\) 的定义的性质。

则有:

\[f_{i} = \sum_{j=1}^{k} f_{i - j}\times g_{j} \]

然后考虑如何预处理 \(g\),显然此时添加 \(j\) 个数的权值是唯一的,于是考虑将添加的数看做 \(1\sim j\),仅需考虑满足上述定义即可。发现上述限制等价于对于添加的 \(j\) 个数中构成的排列 \(1\sim j\),任意小于 \(j\) 的前缀 \(i\) 不能是一个 \(1\sim i\) 的排列。于是考虑容斥,枚举每一个不合法排列最后一个违反限制的前缀。显然第一个不合法前缀为 \(i\) 时,方案数即为子问题 \(g_{i}\),再乘上后面填数的方案数。则显然有:

\[g_{j} = j! - \sum_{i=1}^{j-1} (j-i)!\times g_{i} \]

于是做完了,式子很简洁。总时间复杂度 \(O(k^2 + nk)\)。

虽然场上写了快速取模但实际上常数并不大并无必要,不写也能跑过去。

Code by dztlb:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int lim=1e18;
const int N=1e6+5;
const int mod=998244353;
inline int read(){
	int x=0,f=1; char s;
	while((s=getchar())<'0'||s>'9') if(s=='-') f=-1;
	while(s>='0'&&s<='9') x=(x*10)+(s^'0'),s=getchar();
	return x*f;
}
int n,k;
int a[N],fac[N];

typedef __int128_t i128;
i128 _base=1;
inline int mol(int x){return x-mod*(_base*x>>64);}
int pre[N],onl[N];
signed main(){
	_base=(_base<<64)/mod;

	cin>>n>>k;
	fac[0]=0;fac[1]=1;
	pre[1]=1;
	for(int i=2;i<=n;++i){
		fac[i]=fac[i-1]*i%mod;
		pre[i]=mol(pre[i-1]+fac[i]);
	}
	if(n<k){
		puts("0");
		return 0;
	}
	if(n==k){
		cout << fac[n] << endl;
		return 0;
	}
	a[k]=1;
	onl[1]=1;
	for(int i=2;i<=k;++i){
		onl[i]=fac[i];
		for(int j=1;j<i;++j){
			onl[i]=mol(onl[i]-mol(onl[j]*fac[i-j]));
		}
	}

	a[k]=fac[k];
	for(int x=k+1;x<=n;++x){
		int tmp=0;
		for(int i=1;i<=k;++i){
			if(x-i<k) break;
			a[x] += mol(a[x-i]*onl[i]), a[x] = mol(a[x]);
		}
	}
	cout<<a[n]<<endl;
	return 0;
}

H

二分答案,图论

场上一直跟榜没开这题呃呃,我们是擅长这种经典题的没开到亏亏亏

为了方便讨论钦定 1 为根固定树的形态,考虑二分答案 \(\operatorname{mid}\),枚举 \(m\) 条给定的路径 \((x, y)\) 并检查:

  • 若路径长度 \(\operatorname{dis} \le \operatorname{mid}\),则根可任意取。
  • 否则汇合点一定在路径 \((x, y)\) 上,考虑路径端点 \(x\) 到 \(\operatorname{lca}\) 的长度 \(d\):
    • 若 \(d< \operatorname{mid}\),则合法的汇合点一定在 \(x\) 到其 \(\operatorname{mid}\) 级祖先这条路径上,则 \(x\) 的 \(\operatorname{mid}\) 级祖先的子树内所有点都是合法的;
    • 若 \(d\ge \operatorname{mid}\),则合法的汇合点一定在 \(x\) 到 \(y\) 的 \(\operatorname{dis} - \operatorname{mid}\) 级祖先这条路径上,则除了\(y\) 的 \(\operatorname{dis} - \operatorname{mid}-1\) 级祖先的子树内所有点都是合法的。
    • 另一端点 \(y\) 同理。

若上述所有合法点集有交集,说明有解。发现上述过程中合法的点转化到 dfs 序上至多只有 2 段连续的区间,于是直接差分实现即可。

需要求 \(\operatorname{lca}\) 和节点的 \(k\) 级祖先,使用倍增实现,总时间复杂度 \(O(n\log n + m\log^2 n)\) 级别。

妈的又没特判 0 挂了一发太唐乐。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
//=============================================================
int n, m, x[kN], y[kN], lca[kN], dis[kN];
int edgenum, head[kN], v[kN << 1], ne[kN << 1];
int dfnnum, fa[kN][21], dep[kN], dfn[kN], L[kN], R[kN];
int d[kN];
//=============================================================
void Add(int u_, int v_) {
  v[++ edgenum] = v_;
  ne[edgenum] = head[u_];
  head[u_] = edgenum;
}
void Dfs(int u_, int fa_) {
  L[u_] = dfn[u_] = ++ dfnnum;
  dep[u_] = dep[fa_] + 1;
  fa[u_][0] = fa_;
  for (int i = 1; i <= 18; ++ i) {
    fa[u_][i] = fa[fa[u_][i - 1]][i - 1];
  }
  for (int i = head[u_]; i; i = ne[i]) {
    int v_ = v[i];
    if (v_ == fa_) continue;
    Dfs(v_, u_);
  }
  R[u_] = dfnnum;
}
int Lca(int u_, int v_) {
  if (dep[u_] < dep[v_]) std::swap(u_, v_);
  for (int i = 18; i >= 0; -- i) {
    if (dep[fa[u_][i]] >= dep[v_]) {
      u_ = fa[u_][i];
    }
  }
  if (u_ == v_) return u_;

  for (int i = 18; i >= 0; -- i) {
    if (fa[u_][i] != fa[v_][i]) {
      u_ = fa[u_][i];
      v_ = fa[v_][i];
    }
  }
  return fa[u_][0];
}
int get(int u_, int k_) {
  for (int i = 18; i >= 0; -- i) {
    if (k_ >= (1 << i)) {
      u_ = fa[u_][i];
      k_ -= (1 << i);
    }
  }
  return (k_ == 0) * u_;
}
int Dis(int u_, int v_) {
  return dep[u_] + dep[v_] - 2 * dep[Lca(u_, v_)];
}
bool check(int mid_) {
  for (int i = 0; i <= n; ++ i) d[i] = 0;
  for (int i = 1; i <= m; ++ i) {
    if (dis[i] <= mid_) {
      d[0] += 2;
      continue;
    }
    
    if (dep[x[i]] - dep[lca[i]] > mid_) {
      int p = get(x[i], mid_);
      ++ d[L[p]], -- d[R[p] + 1];
    } else {
      int p = get(y[i], dis[i] - mid_ - 1);
      if (!p) return false;
      ++ d[0], -- d[L[p]], ++ d[R[p] + 1];
    }
    if (dep[y[i]] - dep[lca[i]] > mid_) {
      int p = get(y[i], mid_);
      ++ d[L[p]], -- d[R[p] + 1];
    } else {
      int p = get(x[i], dis[i] - mid_ - 1);
      if (!p) return false;
      ++ d[0], -- d[L[p]], ++ d[R[p] + 1];
    }
  }
  for (int i = 1; i <= n; ++ i) d[i] += d[i - 1];
  for (int i = 0; i <= n; ++ i) if (d[i] == 2 * m) return true;
  return false;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  std::cin >> n >> m;
  for (int i = 1; i < n; ++ i) {
    int u_, v_; std::cin >> u_ >> v_;
    Add(u_, v_), Add(v_, u_);
  }
  Dfs(1, 0);
  for (int i = 1; i <= m; ++ i) {
    std::cin >> x[i] >> y[i];
    lca[i] = Lca(x[i], y[i]);
    dis[i] = Dis(x[i], y[i]);
  }
  
  int ans = n;
  for (int l = 0, r = n; l <= r; ) {
    int mid = (l + r) >> 1;
    if (check(mid)) {
      ans = mid;
      r = mid - 1;
    } else {
      l = mid + 1;
    }
  }
  std::cout << ans << "\n";
  return 0;
}

写在最后

学到了什么:

  • H:对点集的标记转化到 dfs 序上进行。
  • E、H:考虑答案能否取到边界情况!0!0!0!

我是???

标签:std,Invitational,Northeast,Contest,int,LL,mid,long,operatorname
From: https://www.cnblogs.com/luckyblock/p/18398471

相关文章

  • AtCoder Beginner Contest 369 题ABCD详细题解--包含解题思路和两种语言(C++,Python)
    前言:    本文为AtCoderBeginnerContest369题ABCD详细题解,包括题目大意,详细的解题思路和两种语言描述,觉的有帮助或者写的不错可以点个赞几天前的比赛拖的有点久了比赛题目连接:Tasks-AtCoderBeginnerContest369目录题A:题目大意和解题思路:代码(C++):......
  • The 2023 ICPC Asia Nanjing Regional Contest (The 2nd Universal Cup. Stage 11: Na
    C-PrimitiveRoot题意给定p与m(p为质数),已知(g^(P-1))%P==1且g<=m。求g的个数。思路由(g^(P-1))%P==1与异或性质a-b<=a^b<=a+b,可以推出g=((k*p+1)^(p-1))与p*(k-1)+2<=g<=p*(k+1)。又因为g<=m,则当p*(k+1)<=......
  • 2022-2023 ICPC East Central North America Regional Contest (ECNA 2022):JL
    前言这场状态绝对不对劲,rk倒1没啥可说的。A.A-MazingPuzzle这题绝对能做!等我抽空回来补!(不挂在这的话,说不定就摆烂了)J.SimpleSolitaire题意英语阅读理解。自己读去。解法也不写了,纯暴力模拟。认罪认罚具结书好像是第一次当战犯吧。大约3个半小时的时候,我自告奋勇做这......
  • 2019-2020 ICPC Northwestern European Regional Programming Contest (NWERC 2019):GH
    前言目前打过的最逆天的一场,前半场CF评测机度假去了,全场Inqueue,两小时左右评测机终于回来了,Standings遍地开花,听取WA声一片。昨天就有好几道题是因为没及时看题所以没做,赛后还和队友商量说应该先把所有题大致看一遍,结果今天不长记性,还没看H和J,就去写思路不一定对+实现起来难得......
  • SDKD 2024 Summer Training Contest F2(The 13th Shandong ICPC Provincial Collegiat
    A-Orders题意每天能生产k个产品的工厂有n个订单,第i个订单是在a_i天交b_i个产品,问能否交付。思路订单按日期排序,记录剩下的商品.代码#define_CRT_SECURE_NO_WARNINGS#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintmxn=1e6+5......
  • AtCoder Beginner Contest 369 补题记录
    A-369题意:给定A和B,求有多少个x可以和A,B构成等差数列思路:分三种情况讨论A==B则x不得不与A和B想等x位于A和B中间只有B-A为偶数才有这种情况存在x位于A和B两边可以在左边也可以在右边,只要A!=B这种情况总会存在voidsolve(){inta=read(),b=read();......
  • AtCoder Beginner Contest 368(ABC368)
    [ABC369C]CountArithmeticSubarrays题意:判断有多少个区间是等差数列(不能重排)。\(1\len\times10^5\)。思路:赛时看错题了,以为这个区间可以重排,卡了8min,小丑了。首先容易注意到,对于一个区间\([l,r]\),若其是等差数列,则这个区间的子区间\([l',r']\)肯定也是子序列,造成......
  • Atcoder Beginner Contest 369
    AtcoderBeginnerContest369C-CountArithmeticSubarrays题意给出一个长度为\(n\)的序列\(A\),求有多少个\(A\)的连续子序列为等差数列。思路对于递增的右端点,左端点不减。使用双指针,枚举右端点,扫描左端点。时间复杂度:\(O(n)\)。代码#include<bits/stdc++.h>usi......
  • AtCoder Beginner Contest 369 补题记录(A~G)
    AconstintN=1000100;inta[N];signedmain(){intx,y;cin>>x>>y;if(x==y)cout<<"1\n";elseif(x%2==y%2)cout<<"3\n";elsecout<<"2\n";}BconstintN=1000100;inta[N];sign......
  • AtCoder Beginner Contest 369 A~D
    封面原图画师かにょこAtCoderBeginnerContest369我愿称之为等差数列场A-369题意给两个数,问能和他们构成等差数列的数有多少个代码#include<bits/stdc++.h>#definemod998244353usingnamespacestd;typedeflonglongll;typedefdoubledb;type......