emmmm四川省赛的题这么难的嘛。。。。
也不算难,就是做的很憋屈。。。。
A
坑人系列x注意数据范围
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
using namespace std;
using ll = long long;
void OUT(__int128 x) {
static int f[200];
int p = 0;
if (x == 0)
puts("0");
else {
while (x) {
f[p] = x % 10;
x /= 10;
++p;
}
for (int i = p - 1; i >= 0; --i)
putchar('0' + f[i]);
putchar('\n');
}
}
inline int sgn(long long a) {
if (a >= 0)
return 1;
else
return -1;
}
inline __int128 Abs(ll x) {
if (x >= 0)
return x;
else {
__int128 t = x;
t = -t;
return t;
}
}
int main() {
long long a, b;
while (scanf("%lld%lld", &a, &b) != EOF) {
if (sgn(a) * sgn(b) >= 0)
OUT(Abs(a) / Abs(b));
else {
__int128 t1 = Abs(a), t2 = Abs(b);
putchar('-');
OUT(((t1 + t2 - 1) / t2));
}
}
}
B
C
D
E
显然这个转移的图构成DAG,然后你就支配树一下,在支配树上DP算贡献即可。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <vector>
using namespace std;
int const N = 5005;
int const LOGN = 15;
int fa[N][LOGN];
int pre[N];
int f1[N], f2[N];
vector<int> G[N];
int a[N];
int f[N];
int dep[N];
int n;
int get_lca(int x, int y) {
if (dep[x] < dep[y])
swap(x, y);
for (int i = LOGN - 1; i >= 0; --i)
if (dep[fa[x][i]] >= dep[y])
x = fa[x][i];
if (x == y)
return x;
for (int i = LOGN - 1; i >= 0; --i)
if (fa[x][i] != fa[y][i])
x = fa[x][i], y = fa[y][i];
return fa[x][0];
}
void mark(int x, int v) {
int root = x;
while (x != n + 1) {
f1[x] ^= v * v;
if (x != root)
f2[x] ^= (v - 1) * (v - 1);
x = pre[x];
}
}
int main() {
ios::sync_with_stdio(0);
while (cin >> n) {
memset(fa[n + 1], 0, sizeof(fa[n + 1]));
memset(f1, 0, sizeof(f1));
memset(f2, 0, sizeof(f2));
pre[n + 1] = 0;
dep[n + 1] = 1;
int ans = 0;
for (int i = 1; i <= n; ++i) {
G[i].clear();
cin >> a[i];
f[i] = 1;
for (int j = 1; j < i; ++j)
if (a[j] < a[i])
f[i] = max(f[i], f[j] + 1);
for (int j = 1; j < i; ++j)
if (a[j] < a[i] && f[j] == f[i] - 1)
G[i].push_back(j);
if (G[i].size() == 0u)
G[i].push_back(n + 1);
int lca = -1;
for (auto c : G[i]) {
if (lca == -1)
lca = c;
else
lca = get_lca(c, lca);
}
pre[i] = lca;
dep[i] = dep[pre[i]] + 1;
mark(i, f[i]);
fa[i][0] = lca;
for (int j = 1; j < LOGN; ++j)
fa[i][j] = fa[fa[i][j - 1]][j - 1];
ans ^= f[i] * f[i];
}
for (int i = 1; i <= n; ++i)
cout << (ans ^ f1[i] ^ f2[i]) << ' ';
cout << '\n';
}
}
F
这我真不知道应该怎么做,想了想二次曲面还没有旋转的,貌似往8个无穷的方向趋近一下就行的亚子。。。然后再判断一下原点附近就行。
#include <iostream>
#include <cstdio>
using namespace std;
using ll = long long;
using i128 = __int128;
ll const INF = 1e10;
i128 sqr(i128 x) {
return x * x;
}
bool chk(ll x0, ll y0, ll a, ll b, ll c) {
return a * sqr(x0) + i128(b) * x0 * y0 + c * sqr(y0) >= 0;
}
int main() {
int a, b, c;
while (scanf("%d%d%d", &a, &b, &c) != EOF) {
bool ans = 1;
for (int i = -1000; i <= 1000; ++i) {
int C = a * i * i;
int B = b * i;
int A = c;
if (4 * A * C - B * B < 0) {
ans = 0;
break;
}
}
for (int i = -1; i <= 1; ++i)
for (int j = -1; j <= 1; ++j)
ans &= chk(i * INF, j * INF, a, b, c);
if (ans)
puts("Yes");
else
puts("No");
}
}
G
来自新队友的一发提交。
#include <bits/stdc++.h>
using namespace std;
const int K=2017;
int a,b,c,d;
long long A,B,ans;
long long work(int L,int R)
{
int first=0;
for (int i=L;i<=R;i++)
if (!(i%K))
{
first=i;
break;
}
return first?(R-first)/K+1:0;
}
int main()
{
while (scanf("%d%d%d%d",&a,&b,&c,&d)>0)
{
A=work(a,b);
B=work(c,d);
ans=A*(d-c+1)+(b-a+1-A)*B;
printf("%lld\n",ans);
}
return 0;
}
H
I
J
K
bitset压位加速一下就可以了的亚子
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <bitset>
using namespace std;
using ll = long long;
int const MOD = 2017;
ll KSM(ll a, ll k) {
ll ret = 1;
for (; k; k >>= 1, a = a * a % MOD)
if (k & 1)
ret = ret * a % MOD;
return ret;
}
int dfn[2017];
void Yroot() {
int x = 5, t = 1;
for (int i = 1; i < 2017; ++i) {
dfn[x] = t;
x = x * 5 % 2017;
++t;
}
}
int main() {
Yroot();
int n, m;
while (scanf("%d%d", &n, &m) != EOF) {
auto f = bitset<2017>();
for (int o = 1; o <= n; ++o) {
int x;
scanf("%d", &x);
x = dfn[x];
f ^= ((f << x) | (f >> (n - x)));
f[x] = f[x] ^ 1;
}
cout << f[dfn[m]] << '\n';
}
}
L
显然你就枚举一下,就化为3维了,然后复用一下就行。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
using ll = long long;
int const MOD = 1e9 + 7;
ll KSM(ll a, ll k) {
ll ret = 1;
for (; k; k >>= 1, a = a * a % MOD)
if (k & 1)
ret = ret * a % MOD;
return ret;
}
int const N = 100005;
int a[N];
int n;
ll calc(ll s1, ll s2, ll s3) {
static ll inv6 = KSM(6, MOD - 2);
ll fz = KSM(s1, 3) - 3ll * (s2 * s1 % MOD) + 2ll * s3;
fz %= MOD;
if (fz < 0)
fz += MOD;
return fz * inv6 % MOD;
}
int main() {
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
ll sum1 = 0, sum2 = 0, sum3 = 0, ans = 0;
for (int i = 1; i <= n; ++i) {
if (i >= 4)
ans = (ans + a[i] * calc(sum1, sum2, sum3) % MOD) % MOD;
sum1 = (sum1 + a[i]) % MOD;
sum2 = (sum2 + KSM(a[i], 2)) % MOD;
sum3 = (sum3 + KSM(a[i], 3)) % MOD;
}
cout << ans << '\n';
}
}