A 模拟
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 1e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll m_pow(ll x, ll n, ll m) {
ll res = 1;
while (n > 0) {
if (n & 1)
res = (res * x) % m;
x = (x * x) % m;
n >>= 1;
}
return res % m;
}
int main() {
int t, a[N], b[N];
cin >> t;
while (t--) {
int n, flag = 0;
cin >> n;
rep(i, 1, n) cin >> a[i];
rep(i, 1, n) cin >> b[i];
rep(i, 1, n) b[i] = b[i] - a[i];
int p = 1, q = n;
while (b[p] == 0 && p < q)
p++;
while (b[q] == 0 && p < q)
q--;
if (p <= q) {
int a0 = b[p];
rep(i, p , q) {
if (b[i] != a0 || b[i]<0) {
cout << "NO" << endl;
flag = 1;
break;
}
}
}
if (!flag) cout << "YES" << endl;
}
return 0;
}
B 贪心
#include<stdio.h>
#include<set>
#include<iostream>
#include<stack>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>
typedef long long ll;
typedef long double ld;
typedef double db;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int mod = 1e9+7;
int mo(ll a, int p) {
return a >= p ? a % p : a;
}
inline int rd() {
int x = 0, f = 1;
char ch;
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return f * x;
}
int n,x;
int a[1000020];
vector<int>v;
vector<int>k;
int cur,cnt;
int main() {
io_opt;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x;
k.push_back(x);
if(x>0){
if(a[x]==-1||a[x]==1){
cout<<"-1\n";
return 0;
}
else{
a[x]=1;
cur++;
}
}
else{
if(a[-x]!=1){
//cout<<a[x]<<endl;
cout<<"-1\n";
return 0;
}
else{
a[-x]=-1;
cur--;
}
}
cnt++;
if(cur==0){
v.push_back(cnt);
cnt=0;
for(int j=0;j<k.size();j++){
if(k[j]<0) k[j]=-k[j];
a[k[j]]=0;
}
k.clear();
}
}
if(cur!=0){
cout<<"-1\n";
return 0;
}
cout<<v.size()<<endl;
for(int i=0;i<v.size();i++){
cout<<v[i]<<' ';
}
return 0;
}
C 递推
题意是给
n
n
n个数,对于前
k
k
k小的,求出
(
a
1
~
a
m
)
∗
1
+
(
a
m
+
1
~
a
2
m
)
∗
2
(a_1~a_m)*1 + (a_{m+1}~a_{2m})*2
(a1~am)∗1+(am+1~a2m)∗2…
求出前缀和,则
f
i
=
f
i
−
m
+
∑
i
=
1
n
a
i
f_i=f_{i-m} + \sum_{i=1}^n a_i
fi=fi−m+i=1∑nai
#include<stdio.h>
#include<set>
#include<iostream>
#include<stack>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>
typedef long long ll;
typedef long double ld;
typedef double db;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int mod = 1e9+7;
int mo(ll a, int p) {
return a >= p ? a % p : a;
}
inline int rd() {
int x = 0, f = 1;
char ch;
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return f * x;
}
ll n,m;
ll a[200020],ans[200020];
int main() {
io_opt;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
a[i]+=a[i-1];
}
for(int i=1;i<m;i++){
ans[i]=a[i];
}
for(int i=m;i<=n;i++){
ans[i]=ans[i-m]+a[i];
}
for(int i=1;i<=n;i++){
cout<<ans[i]<<' ';
}
return 0;
}
D dfs+贪心
要求求出最少添加多少条边,可以使给出的图满足对于每个
u
u
u,序号为
1
~
u
−
1
1~u-1
1~u−1的点都
u
u
u连通。
dfs出联通块,按照每个联通块中序号最小的点排序;从前向后做,如果当前所有的最大序号大于下一个的最小序号,则加边,同时更新最大值。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 2e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll m_pow(ll x, ll n, ll m) {
ll res = 1;
while (n > 0) {
if (n & 1)
res = (res * x) % m;
x = (x * x) % m;
n >>= 1;
}
return res % m;
}
struct node {
int minn, maxn;
bool operator<(const node &rhs) const {
return minn < rhs.minn;
}
} a[N];
vector<int> v[N];
bool hashv[N] = {0};
int n, m, cnt = 0;
inline void dfs(int k) {
hashv[k] = 1;
a[cnt] = node{min(a[cnt].minn, k), max(a[cnt].maxn, k)};
for (auto x:v[k])
if (!hashv[x])
dfs(x);
}
int main() {
io_opt;
int x, y;
cin >> n >> m;
rep(i, 1, m) {
cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
for (int i = 1; i <= n; i++)
if (!hashv[i]) {
++cnt;
a[cnt] = node{i, i};
dfs(i);
}
sort(a + 1, a + cnt + 1);
int mx = a[1].maxn,ans = 0;
for(int i=2;i<=cnt;i++){
if(a[i].minn < mx)
ans++;
mx=max(mx,a[i].maxn);
}
cout << ans << endl;
return 0;
}
E 区间dp
给 n n n个点( n ≤ 80 n\leq 80 n≤80),每个点可以覆盖到 [ x i − s i , x i + s i ] [x_i-s_i,x_i+s_i] [xi−si,xi+si]的区间,每次花费1个单位的代价可以使任一个点覆盖区间变为 [ x i − s i − 1 , x i + s i + 1 ] [x_i-s_i-1,x_i+s_i+1] [xi−si−1,xi+si+1],求覆盖 [ 1 , m ] [1,m] [1,m]的最小代价。
令 d p i dp_i dpi为覆盖 [ i , m ] [i,m] [i,m]的最小代价,初始化 d p i = m − i dp_i = m-i dpi=m−i,那么对于每一个点灯塔,如果i+1可以被覆盖到, d p i = d p i + 1 dp_i=dp_{i+1} dpi=dpi+1,否则对于 l j > i 的 灯 塔 , u = l j − i − 1 , d p i = m i n ( d p i , u + d p m i n ( m , u + r j ) ) l_j>i的灯塔,u=l_j-i-1,dp_i=min(dp_i,u+dp_{min(m, u+r_j)}) lj>i的灯塔,u=lj−i−1,dpi=min(dpi,u+dpmin(m,u+rj))