Compare commits
18
Commits
79d33854be
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67f1f4d5cc | ||
|
|
97ce969ae3 | ||
|
|
fefae6e22b | ||
|
|
53d14446a0 | ||
|
|
101ef331f6 | ||
|
|
fa496ca42e | ||
|
|
890d0f8f1b | ||
|
|
a31571cb3c | ||
|
|
57392df977 | ||
|
|
796c2a8f44 | ||
|
|
93af6eff6a | ||
|
|
641edbefc9 | ||
|
|
8d6c13ae19 | ||
|
|
25dd0f1a08 | ||
|
|
07fdae11ed | ||
|
|
c9255ff7b9 | ||
|
|
942a77955d | ||
|
|
d75446165d |
+2
-1
@@ -2,6 +2,7 @@
|
||||
!*.cpp
|
||||
!.gitignore
|
||||
!README.md
|
||||
!*.md
|
||||
!solutions
|
||||
!solutions/*.md
|
||||
!clean.sh
|
||||
tmp.md
|
||||
@@ -0,0 +1,98 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int mod = 1e9 + 7;
|
||||
int n, m;
|
||||
int a[100005];
|
||||
const long long fir[4][2] = {{0, 0}, {0, 1}, {0, 2}, {0, 1}};
|
||||
const long long yes[4][4] = {{0, 0, 0, 0}, {0, 1, 0, 0}, {0, 2, 1, 0}, {0, 1, 1, 1}};
|
||||
const long long no[4][4] = {{0, 0, 0, 0}, {0, 1, 0, 1}, {0, 2, 1, 2}, {0, 1, 1, 2}};
|
||||
struct Mat
|
||||
{
|
||||
long long a[5][5] = {};
|
||||
int n, m;
|
||||
Mat(int _n = 0, int _m = 0, int cpy = 0) : n(_n), m(_m)
|
||||
{
|
||||
if (cpy == 1)
|
||||
for (int i = 1; i <= 3; ++i)
|
||||
a[i][1] = fir[i][1];
|
||||
else if (cpy == 2)
|
||||
for (int i = 1; i <= 3; ++i)
|
||||
for (int j = 1; j <= 3; ++j)
|
||||
a[i][j] = yes[i][j];
|
||||
else if (cpy == 3)
|
||||
for (int i = 1; i <= 3; ++i)
|
||||
for (int j = 1; j <= 3; ++j)
|
||||
a[i][j] = no[i][j];
|
||||
}
|
||||
void operator*=(const Mat &b)
|
||||
{
|
||||
if (m != b.n)
|
||||
exit(-1);
|
||||
long long res[5][5] = {};
|
||||
for (int i = 1; i <= n; ++i)
|
||||
for (int j = 1; j <= b.m; ++j)
|
||||
for (int k = 1; k <= m; ++k)
|
||||
res[i][j] = (res[i][j] + a[i][k] * b.a[k][j]) % mod;
|
||||
for (int i = 1; i <= n; ++i)
|
||||
for (int j = 1; j <= b.m; ++j)
|
||||
a[i][j] = res[i][j];
|
||||
m = b.m;
|
||||
}
|
||||
Mat operator*(const Mat &b)
|
||||
{
|
||||
if (m != b.n)
|
||||
exit(-1);
|
||||
Mat res(n, b.m);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
for (int j = 1; j <= b.m; ++j)
|
||||
for (int k = 1; k <= m; ++k)
|
||||
res.a[i][j] = (res.a[i][j] + a[i][k] * b.a[k][j]) % mod;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
Mat qpow(Mat a, long long k)
|
||||
{
|
||||
Mat res(a.n, a.n);
|
||||
for (int i = 1; i <= a.n; ++i)
|
||||
res.a[i][i] = 1;
|
||||
while (k)
|
||||
{
|
||||
if (k & 1)
|
||||
res *= a;
|
||||
a *= a;
|
||||
k >>= 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
Mat yess(3, 3, 2);
|
||||
Mat noo(3, 3, 3);
|
||||
|
||||
int main()
|
||||
{
|
||||
scanf("%d%d", &n, &m);
|
||||
for (int i = 1; i <= m; ++i)
|
||||
scanf("%d", &a[i]);
|
||||
Mat now(3, 1, 1);
|
||||
int pos = 1;
|
||||
for (int i = 1; i <= m; ++i)
|
||||
{
|
||||
int x = a[i];
|
||||
if (x < pos)
|
||||
continue;
|
||||
if (x > pos)
|
||||
{
|
||||
now = qpow(noo, x - pos) * now;
|
||||
}
|
||||
{
|
||||
now = yess * now;
|
||||
}
|
||||
pos = x + 1;
|
||||
}
|
||||
if (n - pos > 0)
|
||||
{
|
||||
now = qpow(noo, n - pos) * now;
|
||||
}
|
||||
printf("%lld\n", now.a[3][1]);
|
||||
return 0;
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
#include <bits/stdc++.h>
|
||||
#define int long long
|
||||
using namespace std;
|
||||
int a, b;
|
||||
int dp[35][35];
|
||||
int getlen(int num)
|
||||
{
|
||||
if (num < 10)
|
||||
return 1;
|
||||
int cnt = 0;
|
||||
while (num)
|
||||
{
|
||||
num /= 10;
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
int calc(int x)
|
||||
{
|
||||
if (x <= 0)
|
||||
return 0;
|
||||
vector<int> digit;
|
||||
while (x)
|
||||
{
|
||||
digit.push_back(x % 10);
|
||||
x /= 10;
|
||||
}
|
||||
int len = digit.size();
|
||||
int res = 0;
|
||||
for (int i = 1; i < len; ++i)
|
||||
{
|
||||
for (int j = 1; j <= 9; ++j)
|
||||
{
|
||||
res += dp[i][j];
|
||||
}
|
||||
}
|
||||
for (int i = len - 1; i >= 0; --i)
|
||||
{
|
||||
int cur = digit[i];
|
||||
int start = (i == len - 1) ? 1 : 0;
|
||||
for (int j = start; j < cur; ++j)
|
||||
{
|
||||
if (i == len - 1 || abs(j - digit[i + 1]) >= 2)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
++res;
|
||||
}
|
||||
else
|
||||
{
|
||||
res += dp[i + 1][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i != len - 1 && abs(cur - digit[i + 1]) < 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
++res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
signed main()
|
||||
{
|
||||
scanf("%lld%lld", &a, &b);
|
||||
int _b = getlen(b);
|
||||
for (int i = 0; i <= 9; ++i)
|
||||
{
|
||||
dp[1][i] = 1;
|
||||
}
|
||||
for (int i = 2; i <= _b; ++i)
|
||||
{
|
||||
for (int j = 0; j <= 9; ++j)
|
||||
{
|
||||
for (int k = 0; k <= 9; ++k)
|
||||
{
|
||||
if (abs(j - k) < 2)
|
||||
continue;
|
||||
dp[i][j] += dp[i - 1][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%lld\n", calc(b) - calc(a - 1));
|
||||
return 0;
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
int t,k;
|
||||
int n;
|
||||
char s[200005];
|
||||
int main(){
|
||||
scanf("%d%d",&t,&k);
|
||||
while(t--){
|
||||
scanf("%d%s",&n,s);
|
||||
bool flag=0;
|
||||
vector<char> ans;
|
||||
for(int i=n-1;i>=0;--i){
|
||||
if((s[i]=='O'&&!flag) || (s[i]=='M' &&flag)){
|
||||
ans.push_back('O');
|
||||
flag=!flag;
|
||||
}else{
|
||||
ans.push_back('M');
|
||||
}
|
||||
}
|
||||
puts("YES");
|
||||
if(k==1){
|
||||
for(int i=n-1;i>=0;--i){
|
||||
putchar(ans[i]);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
MOO
|
||||
MOO
|
||||
*/
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
int n,k;
|
||||
int cs[25][25][25];
|
||||
int calc(int now){
|
||||
int ans=0;
|
||||
for(int i=0;i<n;i++){
|
||||
if(!(now&(1<<i))) continue;
|
||||
for(int j=0;j<n;j++){
|
||||
if((now&(1<<j))) continue;
|
||||
for(int k=j;k<n;k++){
|
||||
if(!(now&(1<<k))){
|
||||
ans+=cs[i][j][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
int main(){
|
||||
scanf("%d%d",&n,&k);
|
||||
for(int i=1;i<=k;++i){
|
||||
int x,y,z;
|
||||
scanf("%d%d%d",&x,&y,&z);
|
||||
x--,y--,z--;
|
||||
if(y>z) swap(y,z);
|
||||
cs[x][y][z]++;
|
||||
}
|
||||
int maxans=0,count=0;
|
||||
for(int i=0;i<=(1<<n)-1;i++){ // 二进制表示棋盘
|
||||
int ci=calc(i);
|
||||
if(ci>maxans) count=1, maxans=ci;
|
||||
else if(ci==maxans) count++;
|
||||
}
|
||||
printf("%d %d\n",maxans,count);
|
||||
return 0;
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long ll;
|
||||
|
||||
int main() {
|
||||
int N, Q;
|
||||
scanf("%d %d", &N, &Q);
|
||||
vector<ll> a(N + 1);
|
||||
for (int i = 1; i <= N; ++i) {
|
||||
scanf("%lld", &a[i]);
|
||||
}
|
||||
const int MAXI = 31;
|
||||
vector<ll> dp(MAXI + 2, 0);
|
||||
dp[1] = a[1];
|
||||
for (int i = 2; i <= MAXI; ++i) {
|
||||
if (i <= N)
|
||||
dp[i] = min(a[i], 2 * dp[i - 1]);
|
||||
else
|
||||
dp[i] = 2 * dp[i - 1];
|
||||
}
|
||||
|
||||
while (Q--) {
|
||||
ll x;
|
||||
scanf("%lld", &x);
|
||||
ll ans = LLONG_MAX;
|
||||
ll cur_cost = 0;
|
||||
bool tight = true;
|
||||
for (int i = 30; i >= 0; --i) {
|
||||
if (tight) {
|
||||
if ((x >> i) & 1LL) {
|
||||
cur_cost += dp[i + 1];
|
||||
} else {
|
||||
ans = min(ans, cur_cost + dp[i + 1]);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ans = min(ans, cur_cost);
|
||||
printf("%lld\n", ans);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const long long MOD = 1000000007LL;
|
||||
|
||||
struct Mat {
|
||||
long long a[105][105];
|
||||
int n, m;
|
||||
|
||||
Mat(int _n = 0, int _m = 0) : n(_n), m(_m) {
|
||||
memset(a, 0, sizeof(a));
|
||||
}
|
||||
|
||||
void operator*=(const Mat &b) {
|
||||
if (m != b.n) {
|
||||
cerr << "矩阵维度不匹配" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
long long res[105][105] = {};
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
for (int j = 1; j <= b.m; ++j) {
|
||||
for (int k = 1; k <= m; ++k) {
|
||||
res[i][j] = (res[i][j] + a[i][k] * b.a[k][j]) % MOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
for (int j = 1; j <= b.m; ++j) {
|
||||
a[i][j] = res[i][j];
|
||||
}
|
||||
}
|
||||
m = b.m;
|
||||
}
|
||||
};
|
||||
|
||||
Mat qpow(Mat a, long long k) {
|
||||
Mat res(a.n, a.n);
|
||||
for (int i = 1; i <= a.n; ++i) {
|
||||
res.a[i][i] = 1;
|
||||
}
|
||||
while (k) {
|
||||
if (k & 1) res *= a;
|
||||
a *= a;
|
||||
k >>= 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main() {
|
||||
long long n;
|
||||
scanf("%lld", &n);
|
||||
|
||||
if (n <= 2) {
|
||||
printf("1\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Mat base1(1, 2), base2(2, 2);
|
||||
|
||||
base1.a[1][1] = 1;
|
||||
base1.a[1][2] = 1;
|
||||
base2.a[1][1] = 1;
|
||||
base2.a[1][2] = 1;
|
||||
base2.a[2][1] = 1;
|
||||
base2.a[2][2] = 0;
|
||||
base2 = qpow(base2, n - 2);
|
||||
base1 *= base2;
|
||||
printf("%lld\n", base1.a[1][1]);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <bits/stdc++.h>
|
||||
#define int long long
|
||||
using namespace std;
|
||||
const int MAXN = 305;
|
||||
int n, m, s[MAXN];
|
||||
vector<int> g[MAXN];
|
||||
int dp[MAXN][MAXN];
|
||||
int sz[MAXN];
|
||||
void dfs(int u)
|
||||
{
|
||||
sz[u] = 1;
|
||||
for (int j = 0; j <= m + 1; ++j)
|
||||
dp[u][j] = INT_MIN;
|
||||
dp[u][1] = s[u];
|
||||
for (int v : g[u])
|
||||
{
|
||||
dfs(v);
|
||||
for (int i = sz[u]; i >= 1; --i)
|
||||
{
|
||||
if (dp[u][i] < 0)
|
||||
continue;
|
||||
for (int k = 1; k <= sz[v] && i + k <= m + 1; ++k)
|
||||
{
|
||||
if (dp[v][k] < 0)
|
||||
continue;
|
||||
dp[u][i + k] = max(dp[u][i + k], dp[u][i] + dp[v][k]);
|
||||
}
|
||||
}
|
||||
sz[u] += sz[v];
|
||||
}
|
||||
}
|
||||
signed main()
|
||||
{
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(nullptr);
|
||||
cin >> n >> m;
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
int fa;
|
||||
cin >> fa >> s[i];
|
||||
g[fa].push_back(i);
|
||||
}
|
||||
s[0] = 0;
|
||||
dfs(0);
|
||||
cout << dp[0][m + 1] << '\n';
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
#define int long long
|
||||
|
||||
int dig[20], len;
|
||||
int dp[20][20][2][2]; // pos, cnt, limm, fl
|
||||
int dfs(int pos, int cnt, bool limm, bool fl, int too)
|
||||
{
|
||||
if (pos == len)
|
||||
return cnt;
|
||||
if (dp[pos][cnt][limm][fl] != -1)
|
||||
return dp[pos][cnt][limm][fl];
|
||||
int up = limm ? dig[pos] : 9;
|
||||
int res = 0;
|
||||
for (int d = 0; d <= up; ++d)
|
||||
{
|
||||
bool nl = fl && (d == 0);
|
||||
int add = 0;
|
||||
if (!(fl && d == 0) && d == too)
|
||||
add = 1;
|
||||
res += dfs(pos + 1, cnt + add, limm && (d == up), nl, too);
|
||||
}
|
||||
return dp[pos][cnt][limm][fl] = res;
|
||||
}
|
||||
int doo(int n, int too)
|
||||
{
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
len = 0;
|
||||
while (n)
|
||||
{
|
||||
dig[len++] = n % 10;
|
||||
n /= 10;
|
||||
}
|
||||
reverse(dig, dig + len);
|
||||
memset(dp, -1, sizeof(dp));
|
||||
return dfs(0, 0, true, true, too);
|
||||
}
|
||||
signed main()
|
||||
{
|
||||
int a, b;
|
||||
cin >> a >> b;
|
||||
for (int i = 0; i <= 9; ++i)
|
||||
{
|
||||
cout << doo(b, i) - doo(a - 1, i) << ' ';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int a, b;
|
||||
int dp[15][15];
|
||||
int getlen(int num)
|
||||
{
|
||||
if (num < 10)
|
||||
return 1;
|
||||
int cnt = 0;
|
||||
while (num)
|
||||
{
|
||||
num /= 10;
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
int calc(int x)
|
||||
{
|
||||
if (x <= 0)
|
||||
return 0;
|
||||
vector<int> digit;
|
||||
while (x)
|
||||
{
|
||||
digit.push_back(x % 10);
|
||||
x /= 10;
|
||||
}
|
||||
int len = digit.size();
|
||||
int res = 0;
|
||||
for (int i = 1; i < len; ++i)
|
||||
{
|
||||
for (int j = 1; j <= 9; ++j)
|
||||
{
|
||||
res += dp[i][j];
|
||||
}
|
||||
}
|
||||
for (int i = len - 1; i >= 0; --i)
|
||||
{
|
||||
int cur = digit[i];
|
||||
int start = (i == len - 1) ? 1 : 0;
|
||||
for (int j = start; j < cur; ++j)
|
||||
{
|
||||
if (i == len - 1 || abs(j - digit[i + 1]) >= 2)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
++res;
|
||||
}
|
||||
else
|
||||
{
|
||||
res += dp[i + 1][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i != len - 1 && abs(cur - digit[i + 1]) < 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
++res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
scanf("%d%d", &a, &b);
|
||||
int _b = getlen(b);
|
||||
for (int i = 0; i <= 9; ++i)
|
||||
{
|
||||
dp[1][i] = 1;
|
||||
}
|
||||
for (int i = 2; i <= _b; ++i)
|
||||
{
|
||||
for (int j = 0; j <= 9; ++j)
|
||||
{
|
||||
for (int k = 0; k <= 9; ++k)
|
||||
{
|
||||
if (abs(j - k) < 2)
|
||||
continue;
|
||||
dp[i][j] += dp[i - 1][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d\n", calc(b) - calc(a - 1));
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#include <bits/stdc++.h>
|
||||
#define int long long
|
||||
using namespace std;
|
||||
struct node
|
||||
{
|
||||
int l, r, num;
|
||||
int lt;
|
||||
} seg[400005];
|
||||
int a[100005];
|
||||
void init(int now, int l, int r)
|
||||
{
|
||||
seg[now].l = l, seg[now].r = r;
|
||||
if (l == r)
|
||||
{
|
||||
seg[now].num = a[l];
|
||||
return;
|
||||
}
|
||||
int mid = l + r >> 1;
|
||||
init(now * 2, l, mid);
|
||||
init(now * 2 + 1, mid + 1, r);
|
||||
seg[now].num = seg[now * 2].num + seg[now * 2 + 1].num;
|
||||
}
|
||||
void pd(int now)
|
||||
{
|
||||
int lt = seg[now].lt;
|
||||
seg[now * 2].num += lt * (seg[now * 2].r - seg[now * 2].l + 1), seg[now * 2].lt += lt;
|
||||
seg[now * 2 + 1].num += lt * (seg[now * 2 + 1].r - seg[now * 2 + 1].l + 1), seg[now * 2 + 1].lt += lt;
|
||||
seg[now].lt = 0;
|
||||
}
|
||||
void add(int now, int l, int r, int num)
|
||||
{
|
||||
if (seg[now].r <= r && seg[now].l >= l)
|
||||
{
|
||||
seg[now].num += num * (seg[now].r - seg[now].l + 1), seg[now].lt += num;
|
||||
return;
|
||||
}
|
||||
if (seg[now].r < l || seg[now].l > r)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pd(now);
|
||||
add(now * 2, l, r, num);
|
||||
add(now * 2 + 1, l, r, num);
|
||||
seg[now].num = seg[now * 2].num + seg[now * 2 + 1].num;
|
||||
}
|
||||
int query(int now, int l, int r)
|
||||
{
|
||||
if (seg[now].l >= l && seg[now].r <= r)
|
||||
{
|
||||
return seg[now].num;
|
||||
}
|
||||
if (seg[now].r < l || seg[now].l > r)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pd(now);
|
||||
return query(now * 2, l, r) + query(now * 2 + 1, l, r);
|
||||
}
|
||||
int n, q;
|
||||
signed main()
|
||||
{
|
||||
scanf("%lld%lld", &n, &q);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
scanf("%lld", &a[i]);
|
||||
init(1, 1, n);
|
||||
while (q--)
|
||||
{
|
||||
int op;
|
||||
scanf("%lld", &op);
|
||||
if (op == 1)
|
||||
{
|
||||
int l, r, k;
|
||||
scanf("%lld%lld%lld", &l, &r, &k);
|
||||
add(1, l, r, k);
|
||||
}
|
||||
else
|
||||
{
|
||||
int l, r;
|
||||
scanf("%lld%lld", &l, &r);
|
||||
printf("%lld\n", query(1, l, r));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#include <bits/stdc++.h>
|
||||
const int mod = 1e9 + 7;
|
||||
#define int long long
|
||||
using namespace std;
|
||||
int n;
|
||||
struct node
|
||||
{
|
||||
int a[105][105];
|
||||
void operator*=(const node &b)
|
||||
{
|
||||
int res[105][105] = {};
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
for (int j = 1; j <= n; ++j)
|
||||
{
|
||||
for (int k = 1; k <= n; ++k)
|
||||
{
|
||||
res[i][j] += (a[i][k] * b.a[k][j]) % mod;
|
||||
res[i][j] %= mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
for (int j = 1; j <= n; ++j)
|
||||
{
|
||||
a[i][j] = res[i][j] % mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
} a;
|
||||
long long k;
|
||||
node pow(node a, int k)
|
||||
{
|
||||
node res;
|
||||
for (int i = 1; i <= n; ++i)
|
||||
for (int j = 1; j <= n; ++j)
|
||||
res.a[i][j] = (i == j);
|
||||
while (k)
|
||||
{
|
||||
if (k & 1)
|
||||
res *= a;
|
||||
a *= a;
|
||||
k >>= 1;
|
||||
}
|
||||
while (k)
|
||||
{
|
||||
if (k & 1)
|
||||
res *= a;
|
||||
a *= a;
|
||||
k >>= 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
signed main()
|
||||
{
|
||||
scanf("%lld%lld", &n, &k);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
for (int j = 1; j <= n; ++j)
|
||||
{
|
||||
scanf("%lld", &a.a[i][j]);
|
||||
}
|
||||
}
|
||||
node res = pow(a, k);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
for (int j = 1; j <= n; ++j)
|
||||
{
|
||||
printf("%lld ", res.a[i][j]);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int n;
|
||||
unsigned long long k;
|
||||
unsigned long long p2[100];
|
||||
string gr(int now, unsigned long long k)
|
||||
{
|
||||
if (now == 1)
|
||||
{
|
||||
if (k == 0)
|
||||
return "0";
|
||||
else
|
||||
return "1";
|
||||
}
|
||||
if (k < p2[now - 1])
|
||||
{
|
||||
return "0" + gr(now - 1, k);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "1" + gr(now - 1, p2[now] - k - 1);
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
p2[0] = 1;
|
||||
for (int i = 1; i <= 99; ++i)
|
||||
p2[i] = p2[i - 1] * 2;
|
||||
scanf("%d%llu", &n, &k);
|
||||
cout << gr(n, k);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long ll;
|
||||
const ll T_BC = 1721424LL;
|
||||
const ll jend = 577737LL;
|
||||
const int ds[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
bool runac(int y) { return y % 4 == 0; }
|
||||
bool runbc(int y) { return y % 4 == 1; }
|
||||
bool runac_new(int y)
|
||||
{
|
||||
return (y % 400 == 0) || (y % 4 == 0 && y % 100 != 0);
|
||||
}
|
||||
ll count_run(ll N)
|
||||
{
|
||||
if (N <= 0)
|
||||
return 0;
|
||||
return N / 4 - N / 100 + N / 400;
|
||||
}
|
||||
ll days_bc(int y)
|
||||
{
|
||||
ll years = 4713 - y;
|
||||
ll leaps = 1179 - (y + 3) / 4;
|
||||
return years * 365 + leaps;
|
||||
}
|
||||
ll days_ac(int y)
|
||||
{
|
||||
ll years = y - 1;
|
||||
ll leaps = years / 4;
|
||||
return years * 365 + leaps;
|
||||
}
|
||||
ll days_new(ll y)
|
||||
{
|
||||
if (y <= 1583)
|
||||
return 0;
|
||||
ll years = y - 1583;
|
||||
ll leaps = count_run(y - 1) - count_run(1582);
|
||||
return years * 365 + leaps;
|
||||
}
|
||||
pair<int, int> gett(ll q, bool run)
|
||||
{
|
||||
int days[13];
|
||||
for (int i = 1; i <= 12; ++i)
|
||||
days[i] = ds[i];
|
||||
if (run)
|
||||
days[2] = 29;
|
||||
int month = 1;
|
||||
while (q >= days[month])
|
||||
{
|
||||
q -= days[month];
|
||||
++month;
|
||||
}
|
||||
return {month, (int)q + 1};
|
||||
}
|
||||
void solve(ll r)
|
||||
{
|
||||
if (r < T_BC)
|
||||
{
|
||||
int el = 1, er = 4713;
|
||||
while (el < er)
|
||||
{
|
||||
int mid = (el + er) / 2;
|
||||
if (days_bc(mid) <= r)
|
||||
er = mid;
|
||||
else
|
||||
el = mid + 1;
|
||||
}
|
||||
int y = el;
|
||||
ll q = r - days_bc(y);
|
||||
bool run = runbc(y);
|
||||
auto [m, d] = gett(q, run);
|
||||
printf("%d %d %d BC\n", d, m, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
r -= T_BC;
|
||||
if (r < jend)
|
||||
{
|
||||
|
||||
int el = 1, er = 1582;
|
||||
while (el < er)
|
||||
{
|
||||
int mid = (el + er + 1) / 2;
|
||||
if (days_ac(mid) <= r)
|
||||
el = mid;
|
||||
else
|
||||
er = mid - 1;
|
||||
}
|
||||
int y = el;
|
||||
ll q = r - days_ac(y);
|
||||
bool run = runac(y);
|
||||
auto [m, d] = gett(q, run);
|
||||
printf("%d %d %d\n", d, m, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
r -= jend;
|
||||
if (r < 78)
|
||||
{
|
||||
int y = 1582, m, d;
|
||||
if (r < 17)
|
||||
{
|
||||
m = 10;
|
||||
d = 15 + r;
|
||||
}
|
||||
else
|
||||
{
|
||||
r -= 17;
|
||||
if (r < 30)
|
||||
{
|
||||
m = 11;
|
||||
d = 1 + r;
|
||||
}
|
||||
else
|
||||
{
|
||||
r -= 30;
|
||||
m = 12;
|
||||
d = 1 + r;
|
||||
}
|
||||
}
|
||||
printf("%d %d %d\n", d, m, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
r -= 78;
|
||||
ll el = 1583, er = 1000000000LL + 1000000;
|
||||
while (el < er)
|
||||
{
|
||||
ll mid = (el + er + 1) / 2;
|
||||
if (days_new(mid) <= r)
|
||||
el = mid;
|
||||
else
|
||||
er = mid - 1;
|
||||
}
|
||||
ll y = el;
|
||||
ll q = r - days_new(y);
|
||||
bool run = runac_new((int)y);
|
||||
auto [m, d] = gett(q, run);
|
||||
printf("%d %d %lld\n", d, m, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
int t;
|
||||
scanf("%d", &t);
|
||||
while (t--)
|
||||
{
|
||||
ll q;
|
||||
scanf("%lld", &q);
|
||||
solve(q);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int n, m1, m2;
|
||||
pair<int, int> plane1[100005], plane2[100005];
|
||||
int f1[100005], f2[100005];
|
||||
int main()
|
||||
{
|
||||
scanf("%d%d%d", &n, &m1, &m2);
|
||||
for (int i = 1; i <= m1; i++)
|
||||
{
|
||||
scanf("%d%d", &plane1[i].first, &plane1[i].second);
|
||||
}
|
||||
sort(plane1 + 1, plane1 + m1 + 1, [](pair<int, int> x, pair<int, int> y)
|
||||
{ return x.first < y.first; });
|
||||
for (int i = 1; i <= m2; i++)
|
||||
{
|
||||
scanf("%d%d", &plane2[i].first, &plane2[i].second);
|
||||
}
|
||||
sort(plane2 + 1, plane2 + m2 + 1, [](pair<int, int> x, pair<int, int> y)
|
||||
{ return x.first < y.first; });
|
||||
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
|
||||
priority_queue<int, vector<int>, greater<int>> freeQ;
|
||||
for (int i = 1; i <= n; i++)
|
||||
freeQ.push(i);
|
||||
for (int i = 1; i <= m1; ++i)
|
||||
{
|
||||
while (!q.empty() && q.top().first <= plane1[i].first)
|
||||
freeQ.push(q.top().second), q.pop();
|
||||
if (!freeQ.empty())
|
||||
{
|
||||
q.push({plane1[i].second, freeQ.top()});
|
||||
f1[freeQ.top()]++;
|
||||
freeQ.pop();
|
||||
}
|
||||
}
|
||||
for (int i = 1; i <= n; i++)
|
||||
{
|
||||
f1[i] += f1[i - 1];
|
||||
}
|
||||
while (!freeQ.empty())
|
||||
freeQ.pop();
|
||||
while (!q.empty())
|
||||
q.pop();
|
||||
for (int i = 1; i <= n; i++)
|
||||
freeQ.push(i);
|
||||
for (int i = 1; i <= m2; ++i)
|
||||
{
|
||||
while (!q.empty() && q.top().first <= plane2[i].first)
|
||||
freeQ.push(q.top().second), q.pop();
|
||||
if (!freeQ.empty())
|
||||
{
|
||||
q.push({plane2[i].second, freeQ.top()});
|
||||
f2[freeQ.top()]++;
|
||||
freeQ.pop();
|
||||
}
|
||||
}
|
||||
for (int i = 1; i <= n; i++)
|
||||
{
|
||||
f2[i] += f2[i - 1];
|
||||
}
|
||||
int maxres = 0;
|
||||
for (int i = 0; i <= n; ++i)
|
||||
{
|
||||
maxres = max(maxres, f1[i] + f2[n - i]);
|
||||
}
|
||||
printf("%d\n", maxres);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int n;
|
||||
int aa[10];
|
||||
bool pd(int now)
|
||||
{
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
int acpy = aa[i];
|
||||
int pp = 0;
|
||||
int cha = 0;
|
||||
int ncpy = now;
|
||||
int xl = 0;
|
||||
for (int j = 1; j <= 5; ++j)
|
||||
{
|
||||
if (acpy % 10 != ncpy % 10)
|
||||
{
|
||||
pp++;
|
||||
|
||||
if (pp == 1)
|
||||
cha = ((acpy % 10 - ncpy % 10) + 10) % 10, xl = j;
|
||||
|
||||
else if (((acpy % 10 - ncpy % 10) + 10) % 10 != cha || abs(j - xl) != 1) return 0;
|
||||
}
|
||||
acpy /= 10, ncpy /= 10;
|
||||
}
|
||||
if (pp > 2 || pp == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
scanf("%d", &n);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
int a, b, c, d, e;
|
||||
scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);
|
||||
aa[i] = 10000 * a + 1000 * b + 100 * c + 10 * d + e;
|
||||
}
|
||||
int ans = 0;
|
||||
for (int i = 0; i <= 99999; i++)
|
||||
{
|
||||
if (pd(i))
|
||||
ans++;
|
||||
}
|
||||
printf("%d\n", ans);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
# AT_agc013_e
|
||||
|
||||
[luoshunran](https://www.acwing.com/file_system/file/content/whole/index/content/14321537/)
|
||||
|
||||
## 20 pts O(n)
|
||||
|
||||
把正方形的交界处看作隔板,在每两个隔板之间放入一黑一白两个球,正方形的大小也就等于区间内放入两个球的方案数,正方形的面积的乘积就是所有的放球方案乘法原理乘起来。于是变成了求有多少种放隔板、放球的方案。
|
||||
|
||||
做 dp $f(i, 0/1/2)$,代表目前这个区间内放入了几个球的方案。
|
||||
|
||||
注意 $f(1, 1) = 2$
|
||||
|
||||
若 $i - i + 1$ 之间可以放隔板,
|
||||
|
||||
- $f(i+1, 0) = f(i, 0) + f(i, 2)$
|
||||
- $ f(i+1, 1) = 2 * f(i, 0) + f(i, 1) + 2 * f(i, 2)$, 这里乘以 2 代表决策放入的是黑球还是白球
|
||||
- $ f(i+1, 2) = f(i, 0) + f(i, 1) + 2 * f(i, 2) $
|
||||
|
||||
类似地,也可以列出不可以放隔板的情况。
|
||||
|
||||
- $f(i+1, 0) = f(i, 0)$
|
||||
- $f(i+1, 1) = 2 * f(i, 0) + f(i, 1)$
|
||||
- $f(i+1, 2) = f(i, 0) + f(i, 1) + f(i, 2)$
|
||||
|
||||
```cpp
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int mod = 1e9 + 7;
|
||||
int n, m;
|
||||
long long f[5000005][3];
|
||||
int a[100005];
|
||||
int main()
|
||||
{
|
||||
scanf("%d%d", &n, &m);
|
||||
for (int i = 1; i <= m; ++i)
|
||||
scanf("%d", &a[i]);
|
||||
sort(a + 1, a + m + 1);
|
||||
int tot = 1;
|
||||
f[1][0] = 1, f[1][1] = 2, f[1][2] = 1;
|
||||
for (int i = 1; i < n; ++i)
|
||||
{
|
||||
if (i == a[tot])
|
||||
{
|
||||
tot++;
|
||||
f[i + 1][0] = f[i][0];
|
||||
f[i + 1][1] = (f[i][0] * 2 + f[i][1]) % mod;
|
||||
f[i + 1][2] = (f[i][0] + f[i][1] + f[i][2]) % mod;
|
||||
}
|
||||
else
|
||||
{
|
||||
f[i + 1][0] = (f[i][0] + f[i][2]) % mod;
|
||||
f[i + 1][1] = (f[i][0] * 2 + f[i][1] + 2 * f[i][2]) % mod;
|
||||
f[i + 1][2] = (f[i][0] + f[i][1] + f[i][2] * 2) % mod;
|
||||
}
|
||||
}
|
||||
printf("%lld\n", f[n][2]);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## 90 pts O(m log n)
|
||||
|
||||
注意到一个区间内需要多次转移,非常浪费。可以考虑使用矩阵快速幂优化。
|
||||
|
||||
对于非标记点,转移矩阵为:
|
||||
|
||||
$$
|
||||
T=\begin{bmatrix}
|
||||
1&0&1\\
|
||||
2&1&2\\
|
||||
1&1&2
|
||||
\end{bmatrix}
|
||||
$$
|
||||
|
||||
对于标记点:
|
||||
|
||||
$$
|
||||
T=\begin{bmatrix}
|
||||
1&0&0\\
|
||||
2&1&0\\
|
||||
1&1&1
|
||||
\end{bmatrix}
|
||||
$$
|
||||
|
||||
初始位置矩阵为:
|
||||
|
||||
$$
|
||||
T=\begin{bmatrix}
|
||||
1\\
|
||||
2\\
|
||||
1
|
||||
\end{bmatrix}
|
||||
$$
|
||||
|
||||
矩阵快速幂代码可参考[P1962](https://luogu.com.cn/problem/P1962)
|
||||
|
||||
```cpp
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const long long MOD = 1000000007LL;
|
||||
struct Mat {
|
||||
long long a[105][105];
|
||||
int n, m;
|
||||
Mat(int _n = 0, int _m = 0) : n(_n), m(_m) {
|
||||
memset(a, 0, sizeof(a));
|
||||
}
|
||||
void operator*=(const Mat &b) {
|
||||
if (m != b.n) {
|
||||
exit(-1);
|
||||
}
|
||||
long long res[105][105] = {};
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
for (int j = 1; j <= b.m; ++j) {
|
||||
for (int k = 1; k <= m; ++k) {
|
||||
res[i][j] = (res[i][j] + a[i][k] * b.a[k][j]) % MOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
for (int j = 1; j <= b.m; ++j) {
|
||||
a[i][j] = res[i][j];
|
||||
}
|
||||
}
|
||||
m = b.m;
|
||||
}
|
||||
};
|
||||
|
||||
Mat qpow(Mat a, long long k) {
|
||||
Mat res(a.n, a.n);
|
||||
for (int i = 1; i <= a.n; ++i) {
|
||||
res.a[i][i] = 1;
|
||||
}
|
||||
while (k) {
|
||||
if (k & 1) res *= a;
|
||||
a *= a;
|
||||
k >>= 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main() {
|
||||
long long n;
|
||||
scanf("%lld", &n);
|
||||
|
||||
if (n <= 2) {
|
||||
printf("1\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Mat base1(1, 2), base2(2, 2);
|
||||
|
||||
base1.a[1][1] = 1;
|
||||
base1.a[1][2] = 1;
|
||||
base2.a[1][1] = 1;
|
||||
base2.a[1][2] = 1;
|
||||
base2.a[2][1] = 1;
|
||||
base2.a[2][2] = 0;
|
||||
base2 = qpow(base2, n - 2);
|
||||
base1 *= base2;
|
||||
printf("%lld\n", base1.a[1][1]);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
最终程序:
|
||||
|
||||
```cpp
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int mod = 1e9 + 7;
|
||||
int n, m;
|
||||
int a[100005];
|
||||
const long long fir[4][2] = {{0, 0}, {0, 1}, {0, 2}, {0, 1}};
|
||||
const long long yes[4][4] = {{0, 0, 0, 0}, {0, 1, 0, 0}, {0, 2, 1, 0}, {0, 1, 1, 1}};
|
||||
const long long no[4][4] = {{0, 0, 0, 0}, {0, 1, 0, 1}, {0, 2, 1, 2}, {0, 1, 1, 2}};
|
||||
struct Mat
|
||||
{
|
||||
long long a[5][5] = {};
|
||||
int n, m;
|
||||
Mat(int _n = 0, int _m = 0, int cpy = 0) : n(_n), m(_m)
|
||||
{
|
||||
if (cpy == 1)
|
||||
for (int i = 1; i <= 3; ++i)
|
||||
a[i][1] = fir[i][1];
|
||||
else if (cpy == 2)
|
||||
for (int i = 1; i <= 3; ++i)
|
||||
for (int j = 1; j <= 3; ++j)
|
||||
a[i][j] = yes[i][j];
|
||||
else if (cpy == 3)
|
||||
for (int i = 1; i <= 3; ++i)
|
||||
for (int j = 1; j <= 3; ++j)
|
||||
a[i][j] = no[i][j];
|
||||
}
|
||||
void operator*=(const Mat &b)
|
||||
{
|
||||
if (m != b.n)
|
||||
exit(-1);
|
||||
long long res[5][5] = {};
|
||||
for (int i = 1; i <= n; ++i)
|
||||
for (int j = 1; j <= b.m; ++j)
|
||||
for (int k = 1; k <= m; ++k)
|
||||
res[i][j] = (res[i][j] + a[i][k] * b.a[k][j]) % mod;
|
||||
for (int i = 1; i <= n; ++i)
|
||||
for (int j = 1; j <= b.m; ++j)
|
||||
a[i][j] = res[i][j];
|
||||
m = b.m;
|
||||
}
|
||||
Mat operator*(const Mat &b)
|
||||
{
|
||||
if (m != b.n)
|
||||
exit(-1);
|
||||
Mat res(n, b.m);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
for (int j = 1; j <= b.m; ++j)
|
||||
for (int k = 1; k <= m; ++k)
|
||||
res.a[i][j] = (res.a[i][j] + a[i][k] * b.a[k][j]) % mod;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
Mat qpow(Mat a, long long k)
|
||||
{
|
||||
Mat res(a.n, a.n);
|
||||
for (int i = 1; i <= a.n; ++i)
|
||||
res.a[i][i] = 1;
|
||||
while (k)
|
||||
{
|
||||
if (k & 1)
|
||||
res *= a;
|
||||
a *= a;
|
||||
k >>= 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
Mat yess(3, 3, 2);
|
||||
Mat noo(3, 3, 3);
|
||||
|
||||
int main()
|
||||
{
|
||||
scanf("%d%d", &n, &m);
|
||||
for (int i = 1; i <= m; ++i)
|
||||
scanf("%d", &a[i]);
|
||||
Mat now(3, 1, 1);
|
||||
int pos = 1;
|
||||
for (int i = 1; i <= m; ++i)
|
||||
{
|
||||
int x = a[i];
|
||||
if (x < pos)
|
||||
continue;
|
||||
if (x > pos)
|
||||
{
|
||||
now = qpow(noo, x - pos) * now;
|
||||
}
|
||||
{
|
||||
now = yess * now;
|
||||
}
|
||||
pos = x + 1;
|
||||
}
|
||||
if (n - pos > 0)
|
||||
{
|
||||
now = qpow(noo, n - pos) * now;
|
||||
}
|
||||
printf("%lld\n", now.a[3][1]);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,111 @@
|
||||
# CF1912E Evaluate It and Back Again题解
|
||||
|
||||
## 题意
|
||||
|
||||
给定两个数,要求你写出一个只包含数字, $+, \times, -$ 的式子,正着看是第一个数,反着看是第二个数。
|
||||
|
||||
## 题解
|
||||
|
||||
观察发现只有**一位数**和 $+, \times$ 的**单项式**倒过来读还是一样的,由 $-0$ 结尾的单项式倒过来读和原式结果相反。
|
||||
|
||||
发现可以将一个要求倒着读后数值不变的数表示为 $9$ 进制的形式,这样多项式中每一项都是倒着读后不变的。
|
||||
|
||||
- 对于两个奇偶性相同的数,可以求两个数的平均数,将 $p, q$ 分别表示为 $p = \overline{pq} + \frac{p - q}{2}, q = \overline{pq} - \frac{p - q}{2}$
|
||||
- 对于两个奇偶性不同的数,也可以求平均数,但是为了让 $p, q$ 奇偶性统一,需要给 $p, q$ 分别减去一个正着读是奇数,反着读是偶数的数,如 $12$,然后即可按照第一种形式做
|
||||
|
||||
然后就是注意特判两个相同的数和 `0 0` 的情况,别忘记开 long long 就结束了
|
||||
|
||||
不懂看注释
|
||||
|
||||
## 参考代码
|
||||
|
||||
```cpp
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
string ans;
|
||||
string to_9(long long n) //转换为正反均相同的多项式
|
||||
{
|
||||
bool flag = n >= 0;
|
||||
if (!flag)
|
||||
n = -n;
|
||||
ans = "";
|
||||
long long cnt = 0;
|
||||
long long yu[20] = {};
|
||||
while (n >= 10ll)
|
||||
yu[cnt++] = n % 9ll, n /= 9ll;
|
||||
yu[cnt] = n;
|
||||
if (!flag)
|
||||
ans += "0-";
|
||||
for (long long i = 0; i <= cnt; ++i)
|
||||
{
|
||||
if (yu[cnt - i] != 0)
|
||||
{
|
||||
for (long long j = 0; j < cnt - i; ++j)
|
||||
ans += "9*";
|
||||
ans += yu[cnt - i] + '0';
|
||||
if (flag)
|
||||
ans += "+0+";
|
||||
else
|
||||
ans += "-0-";
|
||||
}
|
||||
}
|
||||
while (ans[ans.size() - 1] == '+' || ans[ans.size() - 1] == '-')
|
||||
ans.pop_back(); // 去掉多于符号
|
||||
return ans;
|
||||
}
|
||||
string to_9_0(long long n) // 转换为正反读相反的多项式
|
||||
{
|
||||
bool flag = n >= 0;
|
||||
if (!flag)
|
||||
n = -n;
|
||||
ans = "";
|
||||
long long cnt = 0;
|
||||
long long yu[20] = {};
|
||||
while (n >= 10)
|
||||
{
|
||||
yu[cnt++] = n % 9ll;
|
||||
n /= 9ll;
|
||||
}
|
||||
yu[cnt] = n;
|
||||
if (!flag)
|
||||
ans += "0-";
|
||||
for (long long i = 0; i <= cnt; ++i)
|
||||
{
|
||||
if (yu[cnt - i] != 0)
|
||||
{
|
||||
for (long long j = 0; j < cnt - i; ++j)
|
||||
ans += "9*";
|
||||
ans += yu[cnt - i] + '0';
|
||||
if (flag)
|
||||
ans += "-0+";
|
||||
else
|
||||
ans += "+0-";
|
||||
}
|
||||
}
|
||||
while (ans[ans.size() - 1] == '+' || ans[ans.size() - 1] == '-')
|
||||
ans.pop_back(); // 去掉多于符号
|
||||
return ans;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
long long p = 0, q = 0;
|
||||
scanf("%lld%lld", &p, &q);
|
||||
if (abs(p) % 2 == abs(q) % 2) // 同奇偶
|
||||
{
|
||||
long long _pq = p + q >> 1, p_q = p - _pq;
|
||||
if (p == 0 && q == 0) // 特判
|
||||
{
|
||||
puts("0");
|
||||
return 0;
|
||||
}
|
||||
cout << to_9(_pq) << ((_pq != 0 && p_q != 0) ? "+" : "") << to_9_0(p_q) << endl;
|
||||
}
|
||||
else // 异奇偶
|
||||
{
|
||||
long long _pq = (p - 21 + q - 12) >> 1, p_q = p - 21 - _pq; // 转换为同奇偶
|
||||
cout << to_9(_pq) << ((_pq != 0 && p_q != 0) ? "+" : "") << to_9_0(p_q) << ((p_q != 0 || _pq != 0) ? "+" : "") << "21" << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
@@ -0,0 +1,39 @@
|
||||
# [CF739A Alyona and mex](https://www.luogu.com.cn/problem/CF739A)
|
||||
|
||||
## 题意
|
||||
|
||||
给定 $m$ 个区间,构造出一个长度为 $n$ 的序列,使得这 $m$ 个区间的最小 $mex$ 最大。 $mex$ 定义为最小的没有出现过的自然数。
|
||||
|
||||
## 题解
|
||||
|
||||
先观察样例,发现两次输出的 $mex$ 均等于**最短的区间长度**,显然这不是巧合。
|
||||
|
||||
首先很容易得出 $mex(S) \le \lvert S \rvert$,且当 $S$ 覆盖 $0$ 到 $\lvert S \rvert - 1$ 时取等,所以最终答案不会超过最短的区间的长度,然后思考如何构造出答案等于最短区间长度的情况。
|
||||
|
||||
求出最短的区间长度为 $x$,只要让这个区间完全覆盖 $0, 1, 2, ..., x - 1$ ,就可以取到 $mex$ 的最大值,所以则只要在数组中循环填入 $0, 1, 2, ..., x - 1$,就能保证每一个长度大于等于 $x$ 的区间 $mex$ 一定都等于 $x$,因为每一个长度大于等于 $x$ 的区间都至少覆盖一次 $0, 1, 2, ..., x - 1$。(可以自己手搓几个样例试试)
|
||||
|
||||
## 代码
|
||||
|
||||
```cpp
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int main()
|
||||
{
|
||||
int n, m;
|
||||
scanf("%d%d", &n, &m);
|
||||
int minlen = INT_MAX;
|
||||
for (int i = 0; i < m; ++i)
|
||||
{
|
||||
int l, r;
|
||||
scanf("%d%d", &l, &r);
|
||||
minlen = min(minlen, r - l + 1);
|
||||
}
|
||||
printf("%d\n", minlen);
|
||||
int cnt = 0;
|
||||
for (int i = 1; i <= n; ++i)
|
||||
printf("%d ", i % minlen);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
@@ -1,6 +1,4 @@
|
||||
# P13366 [GCJ 2011 #1A] The Killer Word 题解
|
||||
|
||||
参考了 [官方pdf题解](https://www.luogu.com.cn/fe/api/problem/downloadAttachment/zsdw8913)
|
||||
参考了[官方pdf题解](https://www.luogu.com.cn/fe/api/problem/downloadAttachment/zsdw8913)。
|
||||
|
||||
## 思路
|
||||
|
||||
@@ -20,38 +18,26 @@
|
||||
|
||||
对于每个长度,初始时将所有该长度的单词放入同一个候选组。
|
||||
|
||||
一个候选组表示:
|
||||
|
||||
> 在已经猜过的字母及其反馈下,Sean 仍然无法区分的所有单词。
|
||||
一个候选组表示在已经猜过的字母及其反馈下,Sean 仍然无法区分的所有单词。
|
||||
|
||||
对于某个字母,使用一个二进制表示它在单词中出现的位置。
|
||||
|
||||
例如:
|
||||
|
||||
- 单词 `banana`
|
||||
- 字母 `a`
|
||||
- `a` 出现在第 $1,3,5$ 位(下标从 $0$ 开始)
|
||||
|
||||
则对应二进制为:
|
||||
|
||||
$$
|
||||
0101010_2
|
||||
$$
|
||||
例如对于单词 banana 和字母 a,对应二进制为 $101010_2$。
|
||||
|
||||
两个单词对于当前字母得到相同编码,当且仅当 Sean 从黑板上看到的反馈相同,因此它们应被分到同一个新候选组中。
|
||||
|
||||
## 转移过程
|
||||
|
||||
对于一张字母表 `L`:
|
||||
对于一张字母表 L。
|
||||
|
||||
1. 按单词长度初始化候选组。
|
||||
2. 按 `L` 中的顺序枚举每个字母。
|
||||
3. 对每个当前候选组:
|
||||
2. 按 L 中的顺序枚举每个字母。
|
||||
3. 对每个当前候选组。
|
||||
- 若组内只剩一个单词,Sean 已经确定答案,不再需要处理该组。
|
||||
- 计算组内每个单词对当前字母的出现位置二进制表示。
|
||||
- 若所有二进制表示均为 $0$,说明没有候选单词包含该字母,Sean 会跳过该字母,候选组保持不变。
|
||||
- 否则,Sean 会猜该字母:
|
||||
- 二进制为 $0$ 的单词不含该字母,对这些单词的失分加一;
|
||||
- 否则,Sean 会猜该字母。
|
||||
- 二进制为 $0$ 的单词不含该字母,对这些单词的失分加一。
|
||||
- 按二进制表示将原候选组拆分为多个新候选组。
|
||||
4. 所有字母处理结束后,选择失分最多的单词。
|
||||
5. 若失分相同,保留字典中下标较小的单词即可满足题目的平局规则。
|
||||
@@ -60,10 +46,6 @@ $$
|
||||
|
||||
单词长度最大为 $10$,字母表长度固定为 $26$。
|
||||
|
||||
对于每一张字母表,每个单词最多参与 $26$ 次分组,每次计算位置二进制表示需要 $O(10)$。
|
||||
对于每一张字母表,每个单词最多参与 $26$ 次分组,每次计算位置二进制表示。
|
||||
|
||||
因此总时间复杂度为:
|
||||
|
||||
$$
|
||||
O(M \times 26 \times N \times 10)=O(NM)
|
||||
$$
|
||||
因此总时间复杂度为 $O(NM)$,可以通过本题。
|
||||
Reference in New Issue
Block a user