2019牛客暑期多校训练营(第五场)
题号 | 标题 | 已通过代码 | 题解/讨论 | 通过率 | 团队的状态 |
---|---|---|---|---|---|
A | digits 2 | 点击查看 | 进入讨论 | 1016/2378 | 通过 |
B | generator 1 | 点击查看 | 进入讨论 | 513/3524 | 通过 |
C | generator 2 | 点击查看 | 进入讨论 | 34/592 | 已补 |
D | generator 3 | 点击查看 | 进入讨论 | 4/23 | 未通过 |
E | independent set 1 | 点击查看 | 进入讨论 | 36/98 | 队友已补 |
F | maximum clique 1 | 点击查看 | 进入讨论 | 77/779 | 队友已补 |
G | subsequence 1 | 点击查看 | 进入讨论 | 494/2432 | 通过 |
H | subsequence 2 | 点击查看 | 进入讨论 | 278/1311 | 通过 |
I | three points 1 | 点击查看 | 进入讨论 | 125/2614 | 未通过 |
J | three points 2 | 点击查看 | 进入讨论 | 4/70 | 队友已补 |
lwqtql:https://www.cnblogs.com/lwqq3/
zgtql:http://brotherzhi.com/
A
#include
using namespace std;
int T;
int n;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++)printf("%d",n);
puts("");
}
return 0;
}
B
矩阵快速幂
#include
using namespace std;
typedef long long ll;
ll mod;
struct node {
ll c[2][2];
};
node mul(node x, node y) {
node res;
memset(res.c, 0, sizeof(res.c));
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
for(int k = 0; k < 2; k++)
res.c[i][j] = (res.c[i][j] + x.c[i][k] * y.c[k][j] % mod) % mod;
return res;
}
node pow_mod(node x, ll y) {
node res;
res.c[0][0] = res.c[1][1] = 1LL;
res.c[0][1] = res.c[1][0] = 0LL;
while(y) {
if(y & 1) res = mul(res, x);
x = mul(x, x);
y >>= 1;
}
return res;
}
char s[1000005];
int ss[1000005];
int main() {
ll x0, x1, a, b;
cin>>x0>>x1>>a>>b;
scanf("%s", s + 1);
int len = strlen(s + 1);
for(int i = 1; i <= len; i++) ss[i] = s[i] - '0';
cin>>mod;
node A;
A.c[0][0] = a;
A.c[0][1] = b;
A.c[1][0] = 1LL;
A.c[1][1] = 0LL;
if(len == 1) {
if(s[1] == '1') {
printf("%lld\n", x1);
return 0;
}
}
ss[len]--;
for(int i = len; i >= 1; i--) {
if(ss[i] < 0) {
ss[i] += 10;
ss[i - 1]--;
}
}
node now;
now.c[0][0] = now.c[1][1] = 1LL; now.c[0][1] = now.c[1][0] = 0LL;
for(int i = 1; i <= len; i++) {
now = pow_mod(now, 10);
int t = ss[i];
node pp = pow_mod(A, 1LL * t);
now = mul(now, pp);
}
ll ans = now.c[0][0] * x1 % mod + now.c[0][1] * x0 % mod;
ans %= mod;
printf("%lld\n", ans);
return 0;
}
C
写了篇题解https://www.cnblogs.com/1625--H/p/11291238.html
BSGS
E
位元状压DP
#include
using namespace std;
char dp[1 << 26];
int adj[30];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
adj[u] |= (1 << v);
adj[v] |= (1 << u);
}
for(int i = 0; i < n; i++) adj[i] = (~adj[i]), adj[i] ^= (1 << i);
//puts("??");
for(int i = 1; i < (1 << n); i++) {
int t = __builtin_ctz(i);
dp[i] = max(dp[i - (1 << t)], (char)(dp[i & adj[t]] + 1));
}
int ans = 0;
for(int i = 1; i < (1 << n); i++) ans += dp[i];
printf("%d\n", ans);
return 0;
}
G
思路跟标程反了。一直没调对,不知道那里出错了。
下面是按照标程思路写的。思路也不是很难,如果按照长度等不等区分开来进行DP的话,就要额外维护一个东西。
#include
using namespace std;
const int N = 3030;
const int mod = 998244353;
typedef long long ll;
char s[N],t[N];
int n,m;
ll d[N][N],C[N][N];
void predo(){
C[0][0] = 1;
for(int i=1;i=1;j--){
ll sum = j == 1;
for(int i=1;i<=n;i++){
if(s[i] > t[j])
add(res,sum * C[n-i][m-j]);
if(j>1)add(sum,d[i][j-1]);
}
}
cout<
H
对于每两个字母,都能知道单个字符前面有多少个别类字符,所有的情况加起来后就知道前面总共有多少个字符了。不可能的情况可能出现在
- 两次输入中,同一类型字母个数不同
- 总个数不够n个
- 两个字符位置相同
- 有地方空着,或者填入了超出n的位置
#include
using namespace std;
const int N = 10010;
int num[20][10010];
int tot[20];
int n,m;
char s[N];
char ans[10*N];
int main(){
scanf("%d%d",&n,&m);
bool flag = true;
for(int i=1;i<=m*(m-1)/2;i++){
char a,b;
int len;
cin>>a>>b;scanf("%d",&len);
if(len == 0){
getchar();continue;
}
scanf("%s",s);
int cnta = 0,cntb = 0;
for(int i=0;i= n){
flag = false;break;
}
ans[num[i][j] + j-1] = 'a'+i;
}
if(!flag)break;
}
int sum = 0;for(int i=0;i