Codeforces Round 1336 简要题解

发现好久没写题解了,补几场cf的题解。

A. Linova and Kingdom

B. Xenia and Colorful Gems

C. Kaavi and Magic Spell

D. Yui and Mahjong Set

吐了,辛辛苦苦推了一年依次问 1 ∼ n 1\sim n 1n的算法,结果交上去WA了,又分析了半天发现只有当 n > 5 n>5 n>5的时候才能保证正确,于是怒膜题解去了。
题解的询问方式是先依次问 n − 1 , n − 2 , . . . , 3 n-1,n-2,...,3 n1,n2,...,3,然后再依次问 1 , 2 , 1 1,2,1 1,2,1
注意到我们问了 1 1 1两次之后,一定能得到 a 1 a_1 a1(第二次问时考虑triplet的增量为 ( a 1 + 1 2 ) \binom{a_1+1}{2} (2a1+1),这个是可以唯一还原 a 1 a_1 a1的)。同时第一次问 1 1 1时的straight增量为 a 2 ⋅ ( a 3 + 1 ) a_2\cdot (a_3+1) a2(a3+1),而第二次问 1 1 1时的straight增量为 ( a 2 + 1 ) ⋅ ( a 3 + 1 ) (a_2+1)\cdot (a_3+1) (a2+1)(a3+1),因此容易得到 a 2 a_2 a2 a 3 a_3 a3
再注意到对于 i ≥ 4 i\geq 4 i4,若我们已经得到了 a 1 ∼ a i − 1 a_1\sim a_{i-1} a1ai1,那么容易根据问 i − 2 i-2 i2时的straight增量得到 a i a_i ai(减掉已知部分剩下 ( a i − 1 + 1 ) ⋅ a i (a_{i-1}+1)\cdot a_i (ai1+1)ai,直接除即可)。
这样就可以在 n n n次操作后问出 a 1 ∼ a n a_1\sim a_n a1an了。时间复杂度为 O ( n ) \mathcal O(n) O(n)

#include <bits/stdc++.h>

using namespace std;

int a[105],b[105];
int num[105];

int main() {
   
  int n;
  scanf("%d",&n);
  int x,y;
  scanf("%d%d",&x,&y);
  for(int i=n-1;i>2;i--) {
   
  	printf("+ %d\n",i);
  	fflush(stdout);
  	scanf("%d%d",&a[i],&b[i]);
  } 
  printf("+ %d\n",1);
  fflush(stdout);
  scanf("%d%d",&a[1],&b[1]);
  printf("+ %d\n",2);
  fflush(stdout);
  scanf("%d%d",&a[2],&b[2]);
  printf("+ %d\n",1);
  fflush(stdout);
  scanf("%d%d",&x,&y);
  x-=a[2];
  y-=b[2];
  a[2]-=a[1];
  b[2]-=b[1];
  a[1]-=a[3];
  b[1]-=b[3];
  for(int i=3;i<n;i++) {
   
  	a[i]-=a[i+1];
  	b[i]-=b[i+1];
  }
  for(int i=2;i<=n+1;i++)
    if ((i*(i-1)>>1)==x) num[1]=i-1;
  num[3]=y-b[1]-1;
  num[2]=b[1]/(num[3]+1);
  assert(num[1]>=0&&num[2]>=0&&num[3]>=0);
  for(int i=4;i<=n;i++) {
   
  	int s=b[i-2];
  	if (i>4) s-=num[i-3]*num[i-4];
  	s-=(num[i-3]+(i==4))*(num[i-1]+1);
  	num[i]=s/(num[i-1]+1)-(i<n);
  	assert(num[i]>=0);
  }
  printf("! ");
  for(int i=1;i<=n;i++) printf("%d ",num[i]);
  printf("\n");
  fflush(stdout);
  return 0;
} 
/*
5
1 6
1 15
4 20
5 24
5 40
8 48 
*/ 

E2. Chiori and Doll Picking (hard version)

这题好神啊,膜了一天题解。
显然只用考虑线性基里的元素。令线性基大小为 k k k,只用求出只使用线性基里元素的答案再乘上 2 n − k 2^{n-k}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值