A - Equalize Prices Again
分析:向上取整就可以了。
#include "bits/stdc++.h"
using namespace std;
int main() {
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int sum=0,x;
for (int i = 0; i < n; ++i) {
cin>>x;
sum+=x;
}
cout<<(sum+n-1)/n<<endl;
}
}
B1 - Social Network (easy version)&&B2 - Social Network (hard version)
分析:用双端队列维护一下就可以了。另外我想知道这题是不是卡了hash。。。unordered_setT飞了。。。
#include "bits/stdc++.h"
using namespace std;
int main() {
int n, k;
cin >> n >> k;
deque<int> q;
set<int>s;
for (int i = 0; i < n; ++i) {
int x;
scanf("%d",&x);
if (s.count(x))continue;
else {
if (q.size() >= k){
s.erase(q.back());
q.pop_back();
}
q.push_front(x);
s.insert(x);
}
}
cout<<q.size()<<endl;
while(q.size()){
printf("%d ",q.front());
q.pop_front();
}
}
C - Pipes
分析:可以发现走的路线是唯一的,如果当前这个高度下一个格子是1或者2,那么只能直走,如果下一列格子的两个都是3456,那么会改变高度。所以模拟一下就可以了。
#include "bits/stdc++.h"
using namespace std;
char s[200004], t[200004];
int gai(char ch) {
if (ch >= '3')return 2;
else return 1;
}
int main() {
int T;
cin >> T;
while (T--) {
int n;
scanf("%d", &n);
scanf("%s%s", s, t);
int now = 0;
for (int i = 0; i < n; ++i) {
if (gai(t[i]) == 2 && gai(s[i]) == 2)now ^= 1;
else if (now == 0) {
if (gai(s[i]) == 2) {
now = 0;
break;
}
} else if (now == 1) {
if (gai(t[i]) == 2) {
now = 0;
break;
}
}
}
if (now)puts("YES");
else puts("NO");
}
}
D - Distinct Characters Queries
分析:对26个字母分别维护一下区间和就可以了,直接用bit就可以搞完。
#include "bits/stdc++.h"
using namespace std;
struct BIT {
int n;
vector<int> v;
void init(int n){
v.resize(n+1);
}
void update(int x, int d) {
while (x <= n) {
v[x] += d;
x += (x & -x);
}
}
int que(int x) {
int res = 0;
while (x > 0) {
res += v[x];
x -= (x & -x);
}
return res;
}
}bit[26];
char s[100004];
int main() {
for (int i = 0; i < 26; ++i) {
bit[i].init(100004);
bit[i].n = 100004;
}
scanf("%s",s+1);
int n = strlen(s+1);
for (int i = 1; i <= n; ++i) {
bit[s[i]-'a'].update(i,1);
}
int q;
cin>>q;
while(q--){
int op;
scanf("%d",&op);
if(op == 1){
int pos;
char val;
scanf("%d %c",&pos,&val);
bit[s[pos]-'a'].update(pos,-1);
bit[val-'a'].update(pos,1);
s[pos]=val;
}
else {
int l,r;scanf("%d%d",&l,&r);
int ans = 0;
for (int i = 0; i < 26; ++i) {
if(bit[i].que(r) > bit[i].que(l-1))ans++;
}
printf("%d\n",ans);
}
}
}
E - Special Permutations
分析:挺有意思的一道题。显然fp2可以通过fp1转移过来,fp1可以写成m-1个绝对值求和,转移到fp2只需要将fp1中的1变为2,2变为1,普遍一点就是fpn可以通过将fpn-1中的1变为n,n变为1来转移得到。同时显而易见的,对于一个数x,他只会被改变2次,即x->1->x+1,那么每次更新只需要把改变的值重新计算一下就可以了。
#include "bits/stdc++.h"
using namespace std;
int a[200004];
vector<int>v[200004];
pair<int,int>p[200004];
int main() {
int n,m;
cin>>n>>m;
for (int i = 1; i <= m; ++i) {
scanf("%d",&a[i]);
}
long long ans = 0;
for (int i = 1; i < m; ++i) {
ans += abs(a[i] - a[i+1]);
p[i]=make_pair(min(a[i],a[i+1]),max(a[i],a[i+1]));
if(a[i] == a[i+1])continue;
v[a[i]].push_back(i);
v[a[i+1]].push_back(i);
}
printf("%lld ",ans);
for (int i = 2; i <= n; ++i) {
for (int j = 0; j < v[1].size(); ++j) {
ans -= abs(p[v[1][j]].first - p[v[1][j]].second);
if(p[v[1][j]].first == 1)p[v[1][j]].first=i;
if(p[v[1][j]].first > p[v[1][j]].second)swap(p[v[1][j]].first , p[v[1][j]].second);
ans += abs(p[v[1][j]].first - p[v[1][j]].second);
}
for (int j = 0; j < v[i].size(); ++j) {
ans -= abs(p[v[i][j]].first - p[v[i][j]].second);
if(p[v[i][j]].first == i)p[v[i][j]].first=1;
else if(p[v[i][j]].second == i)p[v[i][j]].second=1;
if(p[v[i][j]].first > p[v[i][j]].second)swap(p[v[i][j]].first , p[v[i][j]].second);
ans += abs(p[v[i][j]].first - p[v[i][j]].second);
}
swap(v[1],v[i]);
printf("%lld ",ans);
}
}
F - Yet Another Substring Reverse
分析:用dp[sta]表示sta这个状态的子串是否存在,可以在20*n的时间内求出dp数组。
那么我们要计算答案,朴素的想,枚举一个状态,然后取这个状态的补集,再枚举这个补集的子集,求两者和的最大值。那么我们可以预处理出每个状态的所有子集中的最大值,就可以O(1)转移了。
#include "bits/stdc++.h"
using namespace std;
char s[1000004];
int dp[1<<20];
int main() {
scanf("%s",s);
int n = strlen(s);
memset(dp,0, sizeof(dp));
for (int i = 0; i < n; ++i) {
int now = 0;
for (int j = i; j < n; ++j) {
int x = (1<<(s[j]-'a'));
if(now & x)break;
else now |= x;
dp[now]=j-i+1;
}
}
for (int i = 1; i < (1<<20); ++i) {
for (int j = 0; j < 20; ++j) {
int x = 1 << j;
if(!(i&x))continue;
dp[i]=max(dp[i],dp[i - x]);
}
}
int ans = 0;
for (int i = 0; i < (1<<20); ++i) {
ans =max(ans,dp[i] + dp[(1<<20)-1-i]);
}
cout<<ans<<endl;
}