A 666
将每个数组中的质因子分解,放到一个存质因子和每个质因子位置的二维数组中,每次查询在这个二维数组的质因子中查询最后和最前面的位置,相减即为答案
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define fi first
#define se second
ll gcd(ll a,ll b) {
return b ? gcd(b,a % b) : a;
}
ll power(ll a,ll b) {
ll ans = 1;
while(b) {
if(b % 2 != 0) ans *= a;
a = a * a;
b >>= 1;
}
return ans;
}
typedef pair<ll,ll> PII;
queue<PII> q;
const int N = 2e5 + 5;
ll g[2010][2010],d[2010][2010];
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
void solve() {
int n;
cin >> n;
vector<vector<int>> a(n + 1);
for(int i = 1; i <= n; i++) {
int x;
cin >> x;
for(int j = 2; j * j <= x; j++) {
if(x % j == 0) {
while(x % j == 0) {
x /= j;
}
a[j].push_back(i);
}
}
if(x > 1) a[x].push_back(i);
}
int m;
cin >> m;
while(m--) {
int l,r,x;
cin >> l >> r >> x;
int ans = upper_bound(a[x].begin(),a[x].end(),r) - lower_bound(a[x].begin(),a[x].end(),l);
if(!ans) cout << "666666!" << endl;
else cout << ans << endl;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
// cin >> t;
t = 1;
while(t--) {
solve();
}
return 0;
}
B 求和
n n
B:欧拉反演 n = ∑ φ(n) ,对n属于N都成立. 那么 ∑ ⌊n|d⌋ φ(d) = ∑ ∑ φ(d)即对n求和
(d|n) d=1 i=1 d|i
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define fi first
#define se second
ll gcd(ll a,ll b) {
return b ? gcd(b,a % b) : a;
}
ll power(ll a,ll b) {
ll ans = 1;
while(b) {
if(b % 2 != 0) ans *= a;
a = a * a;
b >>= 1;
}
return ans;
}
typedef pair<ll,ll> PII;
queue<PII> q;
const int N = 2e5 + 5;
ll a[N];
ll g[2010][2010],d[2010][2010];
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
int fact(int n) {
int s = 0,j = 0;
while(n) {
s = s + j * (n % 2);
n /= 2;
j *= 10;
}
return s;
}
/*ll f(ll x)
{
ll res = x;
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0) {
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
if (x > 1) res = res / x * (x - 1);
return res;
}*/
void solve() {
ll n;
cin >> n;
ll sum = 0;
for(int i = 1; i <= n; i++) {
sum += i;
}
cout << sum << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
// t = 1;
while(t--) {
solve();
}
return 0;
}
C 迷宫
将每个位置的数的位置坐标赋值到结构体中,循环每个位置的上下左右是否有比它权值小的数,若无则走不到终点
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define fi first
#define se second
ll gcd(ll a,ll b) {
return b ? gcd(b,a % b) : a;
}
ll power(ll a,ll b) {
ll ans = 1;
while(b) {
if(b % 2 != 0) ans *= a;
a = a * a;
b >>= 1;
}
return ans;
}
typedef pair<ll,ll> PII;
queue<PII> q;
const int N = 2e5 + 5;
// ll a[N];
ll g[2010][2010],d[2010][2010];
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
void solve() {
int n,m;
cin >> n >> m;
vector<vector<int>> a(n + 1,vector<int> (m + 1));
vector<PII> q(n * m + 1);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
cin >> a[i][j];
q[a[i][j]] = {i,j};
}
}
string ans = "YES";
for(int i = 2; i <= n * m; i++) {
bool f = 0;
for(int j = 0; j < 4; j++) {
int x = q[i].fi + dx[j];
int y = q[i].se + dy[j];
if(x < 1 || x > n || y < 1 || y > m) continue;
if(a[x][y] < i) f = 1;
}
if(!f) ans = "NO";
}
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
D 操作序列1
先将每个算法的位置对应赋值,若已经学会就将其和下一个算法进行合并,直至都合并到一个未学习过的算法中
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define fi first
#define se second
ll gcd(ll a,ll b) {
return b ? gcd(b,a % b) : a;
}
ll power(ll a,ll b) {
ll ans = 1;
while(b) {
if(b % 2 != 0) ans *= a;
a = a * a;
b >>= 1;
}
return ans;
}
typedef pair<ll,ll> PII;
queue<PII> q;
const int N = 2e6 + 5;
ll a[N];
ll g[2010][2010],d[2010][2010];
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
int find(int x) {
return a[x] == x ? x : a[x] = find(a[x]);
}
void solve() {
int n,m;
cin >> n >> m;
for(int i = 0; i <= n + 1; i++) {
a[i] = i;
}
while(m--) {
ll ans = 0;
int l,r;
cin >> l >> r;
for(int i = find(l); i <= r; i = find(i + 1)) {
ans++;
a[i] = i + 1;
}
cout << ans << endl;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
// cin >> t;
t = 1;
while(t--) {
solve();
}
return 0;
}
F NB数
对操作次数进行二分,如果遇到不是NB数,操作次数减一将它变成0使它变成NB数,返回成立的操作次数,循环寻找最少的操作次数
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define fi first
#define se second
ll gcd(ll a,ll b) {
return b ? gcd(b,a % b) : a;
}
ll power(ll a,ll b) {
ll ans = 1;
while(b) {
if(b % 2 != 0) ans *= a;
a = a * a;
b >>= 1;
}
return ans;
}
typedef pair<ll,ll> PII;
queue<PII> q;
const int N = 1e5 + 5;
ll a[N],n,m;
ll g[2010][2010],d[2010][2010];
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
bool check(int x) {
int ans = 0;
for(int i = 1; i <= n; i++) {
if(ans >= a[i]) {
ans++;
} else if(x) {
x--;
ans++;
}
}
return ans >= m;
}
void solve() {
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i];
int l = 0,r = m;
while(l < r) {
int mid = (l + r) >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
cout << r << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
// cin >> t;
t = 1;
while(t--) {
solve();
}
return 0;
}
G 跑步计划
求最多能删除的边,如果i,j两点之间存在一点k使得i可以通过k到达j的距离比i直接到j的距离更短,那么此时i到j的这条边可以删除,无向图最后要删除的边需要除2
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define fi first
#define se second
ll gcd(ll a,ll b) {
return b ? gcd(b,a % b) : a;
}
ll power(ll a,ll b) {
ll ans = 1;
while(b) {
if(b % 2 != 0) ans *= a;
a = a * a;
b >>= 1;
}
return ans;
}
typedef pair<ll,ll> PII;
queue<PII> q;
const int N = 305;
ll a[N],cnt[N][N];
ll g[2010][2010],d[2010][2010];
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
int MIN(int a,int b) {
return a < b ? a : b;
}
void solve() {
memset(d,0x3f,sizeof d);
int n,m;
cin >> n >> m;
for(int i = 1; i <= n; i++) d[i][i] = 0;
for(int i = 1; i <= m; i++) {
int u,v,w;
cin >> u >> v >> w;
d[u][v] = MIN(d[u][v],w);
d[v][u] = MIN(d[v][u],w);
cnt[u][v] = 1;
cnt[v][u] = 1;
}
for(int k = 1; k <= n; k++) {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
d[i][j] = min(d[i][j],d[i][k] + d[k][j]);
}
}
}
ll ans = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i == j) continue;
for(int k = 1; k <= n; k++) {
if(k == i || k == j) continue;
if(cnt[i][j] && d[i][j] == d[i][k] + d[k][j]) {
ans++;
break;
}
}
}
}
cout << ans / 2;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
// cin >> t;
t = 1;
while(t--) {
solve();
}
return 0;
}
H 中位数?中位序列!
通过枚举可以发现当k为偶数的情况下,中位序列都是k/2为开头,后面都是k的序列。k为奇数时,第一位一定是(k + 1) / 2(模拟就可得),后面需要进行1到n / 2次循环处理将(k + 1) / 2每次进行减一,当其本就是一时则将其删除(可以通过最简单的n为5 k为1样例模拟),而通过n为8,k为3的例子可得若最后一项删除并继续进行减一操作时,需要将其减一后在后一项添加一项赋值为k(不太懂啥原理只能模拟出来qwq)
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define fi first
#define se second
ll gcd(ll a,ll b) {
return b ? gcd(b,a % b) : a;
}
ll power(ll a,ll b) {
ll ans = 1;
while(b) {
if(b % 2 != 0) ans *= a;
a = a * a;
b >>= 1;
}
return ans;
}
typedef pair<ll,ll> PII;
queue<PII> q;
const int N = 2e5 + 5;
ll a[N];
ll g[2010][2010],d[2010][2010];
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
void solve() {
int n,k;
cin >> n >> k;
if(k % 2 == 0) {
cout << k / 2 << ' ';
for(int i = 2; i <= n; i++) {
cout << k << ' ';
}
} else {
for(int i = 1; i <= n; i++) a[i] = (k + 1) / 2;
int tt = n;
for(int i = 1; i <= n / 2; i++) {
if(a[tt] == 1) {
tt--;
} else {
a[tt]--;
while(tt < n) a[++tt] = k;
}
}
for(int i = 1; i <= tt; i++) {
cout << a[i] << ' ';
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
// cin >> t;
t = 1;
while(t--) {
solve();
}
return 0;
}
I 仙跳墙
将xyz存入一个判断数组cnt中,xyz的位置cnt为1,在cnt为0时进行dp,因为编号小的都在编号大的之前,所以确定最大的i和j更新答案,此时的答案就是在没有连续使用编号为xyz下的答案
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define fi first
#define se second
ll gcd(ll a,ll b) {
return b ? gcd(b,a % b) : a;
}
ll power(ll a,ll b) {
ll ans = 1;
while(b) {
if(b % 2 != 0) ans *= a;
a = a * a;
b >>= 1;
}
return ans;
}
typedef pair<ll,ll> PII;
queue<PII> q;
const int N = 105;
ll val[N],time1[N],cnt[N][N][N],dp[N][N][N];
ll g[2010][2010],d[2010][2010];
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
int max(int a,int b) {
return a > b ? a : b;
}
void solve() {
int n,T,m;
cin >> n >> T >> m;
for(int i = 2; i <= n + 1; i++) {
cin >> val[i] >> time1[i];
}
for(int i = 1; i <= m; i++) {
int x,y,z;
cin >> x >> y >> z;
x++;y++;z++;
cnt[x][y][z] = 1;
}
ll ans = 0;
for(int i = 2; i <= n + 1; i++) {
for(int j = 0; j < i; j++) {
for(int k = 0; k < j; k++) {
if(!cnt[k][j][i]) {
for(int p = time1[i]; p <= T; p++) {
dp[i][j][p] = max(dp[i][j][p],dp[j][k][p - time1[i]] + val[i]);
ans = max(ans,dp[i][j][p]);
}
}
}
}
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
// cin >> t;
t = 1;
while(t--) {
solve();
}
return 0;
}