洛谷 8 月月賽 & 「PMOI」Round · 04
阿新 • • 發佈:2021-08-21
T1 T166167 「PMOI-4」人贏
題目大意
給一個數列的前兩項分別為\(n\)和\(m\)
當\(i\geq3\)時\(a_i = a_{i-1}*a_{i-2}\)的個位
給定\(n\),\(m\),\(k\), 求以\(n\)和\(m\)為前兩項的數列的第\(k\)項
(資料範圍 $0 \leq n,m \leq 9 $ \(1 \leq k \leq 1e12\)
思路
通過觀察樣例可以發發現 \(n,m\)很小 \(k\)很大 因此這道題肯定是有規律的
通過打表我們可以發現 這個數列從第三項開始 每 六項 重複一次
因此我們可以通過找到數列的前六項來找到第\(k\)個數字是多少
AC_CODE
#include <bits/stdc++.h> #define x first #define y second //#define int long long #define endl '\n' using namespace std; typedef pair<int, int> PII ; typedef long long LL; template < typename T > inline void read(T &x) { x = 0; bool f = 0; char ch = getchar(); while(!isdigit(ch)){f ^= !(ch ^ 45);ch=getchar();} while(isdigit(ch)) x= (x<<1)+(x<<3)+(ch&15),ch=getchar(); x = f ? -x : x; } const int N = 2e5 + 10; int a[N]; void solve() { int n, k; read(n), read(k); LL ans = 0; for(int i = 1; i <= n; i ++ ) { read(a[i]); ans += a[i]; } sort(a + 1, a + 1 + n); int res = n - k; if(res >= 2) cout << a[(res + 1) / 2] << endl; else { if(res == 0) cout << 0 << endl; else if(res == 1) cout << ans << endl; } } signed main() { int T = 1; scanf("%d",&T); while(T -- ) { solve(); } return 0; }
T2 「PMOI-4」生成樹
題意
給定一個數組
a[]
我們每次取出這個數列中的一個數字放入新陣列中
當這個數字在新陣列中的下標為i
這個數字原本為k
時 其他的數字
加上\(-1^{i+k+1}k\) 求新陣列中所有的數字最大的和
思路
我們需要求所有的數字最大的和,基於貪心的思想,我們要讓每個數字儘可能的大
當某個數字先選的時候 他會對後面的造成影響,因此我們要讓這個影響儘可能的大
可以使後面的數字儘可能的大
由此add
受到下標i
和k
的 奇偶性問題 我們做出以下分析
- 當我們填到第奇數個數字時 我們需要讓它對後面的影響為正
-i+k+1
是奇數 且k
是負數
-i+k+1
是偶數 且k
- \(|k|\) 儘可能的大(對後面的影響更大
- 如果上述兩種情況不存在,我們優先去放0
(0對後面無影響
- 如果以上都不存在,我們只能放對後面造成負影響的數字,因此我們讓它絕對值儘可能小 - 偶數同上
AC_CODE
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define debug(x) cout<<#x" ----> "<<x<<endl
#define rep(i, b, s) for(int i = (b); i <= (s); ++i)
#define pre(i, b, s) for(int i = (b); i >= (s); --i)
//#define int long long
#define endl '\n'
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
#define all(v) (v).begin(),(v).end()
using namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII ;
typedef pair<double, double> PDD ;
typedef long long LL;
const int N = 1e5 + 10;
int n;
PII a[N];
int b[N];
bool cmp(PII p, PII q) {
return abs(p.x) < abs(q.x);
}
void solve() {
scanf("%d", &n);
vector<PII> l, r;
int cnt = 0;
for(int i = 0; i < n; i ++ ) {
int x;
scanf("%d", &x);
b[i] = x;
if(!x) cnt ++;
else if(x < 0 && x & 1 || x > 0 && !(x & 1)) l.pb({x, i});
else r.pb({x, i});
}
sort(all(l), cmp);
sort(all(r), cmp);
int len1 = l.size(), len2 = r.size();
int t1 = len1 - 1, t2 = len2 - 1, e1 = 0, e2 = 0;
for(int i = 0; i < n; i ++ ) {
if((i + 1) & 1) {
if(t1 >= e1) {
a[i] = l[t1 --];
}
else if(cnt) {
a[i] = {0, 0};
cnt --;
}
else a[i] = r[e2 ++];
}
else {
if(t2 >= e2) a[i] = r[t2 -- ];
else if(cnt) {
a[i] = {0, 0};
cnt --;
}
else a[i] = l[e1 ++];
}
}
// for(int i = 0; i < n; i ++ )
// printf("%d %d\n", a[i].x, a[i].y);
LL res = 0, ans = 0;
int t = 1;
for(int i = 0; i < n; i ++, t ^= 1 ) {
if(a[i].x == 0) {
ans += res;
continue;
}
ans += (res + a[i].x);
int p = b[a[i].y];
if((t + 1 + p) % 2 == 0) res += p;
else res -= p;
}
printf("%lld", ans);
}
signed main()
{
int T = 1; //scanf("%d",&T);
while(T -- ) {
solve();
}
return 0;
}