C
题意:一个序列a,对序列a进行操作,每次吧序列a的第一个元素插入序列b的末端,然后反转序列b,问最后的到的序列b
思路:由题可以反向推理,假设已经有了序列b,然后反转序列b,此时序列b中bn的元素等于an, 去掉bn,然后再反转序列b,此时b序列中末端是b1,可知b1等于an-1,继续下去即可。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int qq = 2e5 + 10;
int a[qq], b[qq];
int main(){
int n; scanf("%d", &n);
REP(i, 1, n){
scanf("%d", a + i);
}
int l = 1, r = n;
int cnt = 1, p = n;
for(int i = n; i >= 1; --i){
if(cnt & 1) b[l++] = a[p--];
else b[r--] = a[p--];
cnt++;
}
REP(i, 1, n - 1){
printf("%d ", b[i]);
}
printf("%d\n", b[n]);
return 0;
}
D
题意:给出一个有n + 1元素的序列,要你找出有多少种不相同的子序列
思路:注意到只有一个数字会出现两次,反向思维先得到Cn,k 然后我们减去重复的,
比如 2 3 1 4 5 1 6
可知如果某个序列包含了1 1,那么前后两个1是互不影响的。
如果同时不包含 1 1,那么也都不会算重
只包含一个1的情况下,并且不包含两个1之间元素的序列是会有重复,比如选第一个1时, 2 3 1,选第二个1时, 2 3 1。
最后得到Cn,k - Cn - d(两个1之间的距离),k - 1。
注意的用逆元,直接算mod的结果是不对的
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2e5 + 10;
int num[qq];
LL inv[qq];
map<int, int> mp;
LL Power(LL x, LL t){
LL ret = 1;
while(t > 0){
if(t & 1) ret = (ret * x) % MOD;
x = (x * x) % MOD;
t >>= 1;
}
return ret;
}
LL Calc(int a, int b){
if(a < b) return 0;
return inv[a] * Power(inv[b], MOD - 2) % MOD * Power(inv[a - b], MOD - 2) % MOD;
}
int main(){
LL n; scanf("%lld", &n);
bool f = false;
int l, r;
REP(i, 1, n + 1){
int x;scanf("%d", &x);
num[x]++;
if(!f){
if(num[x] == 2){
l = mp[x];
r = i;
f = true;
}
}
mp[x] = i;
}
++n;
inv[0] = 1LL;
REP(i, 1, n){
inv[i] = inv[i - 1] * (LL)i % MOD;
}
REP(i, 1, n){
printf("%lld\n", (((Calc(n, i) - Calc(n - r + l - 1, i - 1)) % MOD + MOD) % MOD));
}
return 0;
}