这道题目还是问我学长的(感谢dailingx学长),一开始有想法写,但是不知道WA在了什么地方,网上也没有什么题解,整理出来。
题目链接
#include
#define inf 0x3f3f3f3f
#define llinf 1ll<<60
using namespace std;
typedef long long ll;
ll read() {
ll x = 0;
ll ch = getchar();
while (ch < '0' || ch > '9') {
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + (ll)(ch - '0');
ch = getchar();
}
return x;
}
void out(ll a) {
if (a < 0) {
putchar('-');
a = -a;
}
if (a >= 10) {
out(a / 10);
}
putchar(a % 10 + '0');
}
ll a[200010];
ll num[2000];
ll sum[200010];
ll tot[2000];
int main() {
ll n, m, k;
ll p;
while(~scanf("%lld%lld%lld%lld", &k, &m, &n, &p)) {//n叉 m层
ll cnt = 0, t = 1, ans = 0;
sum[0] = 0;
for (ll i = 1; i <= k; i++) {
a[i] = read();
sum[i] = sum[i-1] + a[i];
}
num[1] = 0;
tot[2] = 1;
for (ll i = 2; i <= m; i++) {
t *= n;
cnt += t;
num[i] = num[i-1] + t;//到当前层有多少条边
tot[i+1] = tot[i] + t;//当前层每条边需要使用多少次
}
sort(a+1, a+k+1);
for (ll i = 1; i <= cnt; i++) {
sum[i] = (sum[i-1] + a[i]) % p;
}
for (ll i = 2; i <= m; i++) {
ans = (ans + ((((sum[num[i]] - sum[num[i-1]] + p) % p)) * tot[m-i+2]) % p) % p;
}
out(ans);
putchar('\n');
}
return 0;
}
/*
13 3 3 10000
1 2 3 4 5 6 7 8 9 10 11 12 13
*/
题目链接
这道题目给出两种方法,看你自己能理解那种。
这道题目可以用这样的技巧,就像求不止一次的子序列一样。
(主要是我看没人写这个重现赛的题解,然后我这个菜鸟就到处寻找过来QWQ)
#include
#define ll long long
using namespace std;
const int maxn = 3005;
char st[200005];
int main() {
int n;
while(~scanf("%d", &n)) {
scanf("%s", st);
int sumx = 0, sumt = 0, sumC = 0, sump = 0, sumc = 0;
for(int i = 0; i < n; ++i) {
if(st[i] == 'x') sumx += 1;
if(st[i] == 't' && sumx > sumt) sumt += 1;
if(st[i] == 'C' && sumt > sumC) sumC += 1;
if(st[i] == 'p' && sumC > sump) sump += 1;
if(st[i] == 'c' && sump > sumc) sumc += 1;
}
printf("%d\n", sumc);
}
return 0;
}
如果不会技巧的话也可以暴力写
#include
#define ll long long
using namespace std;
const int maxn = 3005;
char st[200005];
char s[200005];
int ax[200005], at[200005], aC[200005], ap[200005], ac[200005];
int main() {
int n;
while(~scanf("%d", &n)) {
scanf("%s", st);
int t = -1;
for(int i = 0; i < n; ++i) {
if(st[i] == 'x') {
t = i;
break;
}
}
if(t == -1) {
printf("0\n");
} else {
int cnt = 0;
int xx = 0, xt = 0, xC = 0, xp = 0, xc = 0;
for(int i = t; i < n; ++i) {
if(st[i] == 'x') ax[xx++] = i;
if(st[i] == 't') at[xt++] = i;
if(st[i] == 'C') aC[xC++] = i;
if(st[i] == 'p') ap[xp++] = i;
if(st[i] == 'c') ac[xc++] = i;
}
int i = 0, j = 0, p = 0, x = 0, y = 0;
while(i < xx && j < xt && p < xC && x < xp && y < xc) {
if(at[j] > ax[i]) {
if(aC[p] > at[j]) {
if(ap[x] > aC[p]) {
if(ac[y] > ap[x]) {
i += 1;
j += 1;
p += 1;
x += 1;
y += 1;
cnt += 1;
} else {
y += 1;
}
} else {
x += 1;
}
} else {
p += 1;
}
} else {
j += 1;
}
}
printf("%d\n", cnt);
}
}
return 0;
}