发现已经错过最美的花期|

ricky_lin

园龄:3年8个月粉丝:11关注:2

【题解】CF1213 合集

CF1213A Chips Moving

考虑是一道非常简单的入门题

就是奇数的个数和偶数的个数取 \(\min\) 即可

code
#include<bits/stdc++.h>
using namespace std;
const int NN = 108;
int n;
int a,cnt[2];
int main(){
scanf("%d",&n);
for(int i = 1; i <= n; ++i){
scanf("%d",&a);
++cnt[a&1];
}
printf("%d",min(cnt[0],cnt[1]));
}

CF1213B Bad Prices

我们从后往前更新答案,每次维护后缀最小值即可

code
#include<bits/stdc++.h>
using namespace std;
const int NN = 2e5 + 8;
int T,n;
int a[NN];
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
int mn = 0x3f3f3f3f,ans = 0;
for(int i = n; i >= 1; --i){
mn = min(a[i],mn);
ans += mn != a[i];
}
printf("%d\n",ans);
}
}

CF1213C Book Reading

这道题目,我们可以发现显然是有周期性的

我们个位数都可以统一成以 \(10\) 为一轮,然后就可以快速求解(预处理周期即可)

code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int q;
ll n,m;
int a[10] = {0,45,40,45,40,25,40,45,40,45};
int main(){
scanf("%d",&q);
for(int i = 1; i <= q; ++i){
ll ans = 0;
scanf("%lld%lld",&n,&m);
int base = m % 10;
ll cnt = n / m;
for(int i = 1; i <= cnt % 10; ++i){
ans += i * base % 10;
}
ans += cnt / 10 * a[base];
printf("%lld\n",ans);
}
}

CF1213D Equalizing by Division (EZ&HD)

标签:字符串 \(C^+\)

我们可以发现,最后剩下的数字一定是只剩下高位。

我们这道题可以建出一个 01trie 然后就可以进行求解。

我们按所有数转化为二进制后的长度从小到大推入 01trie

然后我们就可以对于每个节点记录前 \(k\) 个遍历到这个节点的全部将这个节点后面的数字去掉的代价

可以证明从小到大加入后前 \(k\) 个遍历到的一定是最优解之一

最后对于每个节点记录的值取 \(\min\) 即可

code
#include<bits/stdc++.h>
using namespace std;
const int NN = 2e5 + 8;
int n,k;
int a[NN];
string s[NN];
vector<int> ans;
struct Trie{
int son[2];
int num,res;
#define l(x) T[x].son[0]
#define r(x) T[x].son[1]
#define son(x,y) T[x].son[y-'0']
#define num(x) T[x].num
#define res(x) T[x].res
}T[NN << 4];
int cnt = 1;
void insert(int p){
int now = 1;
if(num(now) < k) ++num(now),res(now) += s[p].size();
for(int i = 0; i < s[p].size(); ++i){
if(son(now,s[p][i]) == 0){
son(now,s[p][i]) = ++cnt;
}
now = son(now,s[p][i]);
if(num(now) < k){
++num(now),res(now) += s[p].size() - i - 1;
if(num(now) == k) ans.push_back(res(now));
}
}
}
bool cmp(string &x,string &y){
return x.size() < y.size();
}
int main(){
scanf("%d%d",&n,&k);
for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
for(int j = 1; j <= n; ++j){
if(a[j] == 0) s[j] = "0";
while(a[j]){
s[j] += (a[j] & 1) + '0';
a[j] >>= 1;
}
reverse(s[j].begin(),s[j].end());
}
sort(s+1,s+1+n,cmp);
for(int i = 1; i <= n; ++i) insert(i);
sort(ans.begin(),ans.end());
printf("%d",ans[0]);
}

CF1213E Two Small Strings

标签:思维题 \(C^-\)

考虑这道题目显然还是很简单

我们考虑构造,很容易想到一种方法就是找到一个 \(abc\) 的排列,最后重复 \(n\)

但是我们会发现这样一组数据:

3
ab
ac

我们显然对于上面的一组数据就不能这样构造。

但是我们有另外一组构造方法:\(bbbcccaaa\)

就是对于 \(bca\) 这个排列来说,每个字母重复 \(n\) 遍即可

最后将两个构造方法合并即可通过本题。

code
#include<bits/stdc++.h>
using namespace std;
bool a[3][3];
int n;
char s[10];
int main(){
memset(a,1,sizeof(a));
scanf("%d",&n);
for(int i = 1; i <= 2; ++i){
scanf("%s",s);
a[s[0]-'a'][s[1]-'a'] = 0;
}
if(a[0][0] && a[1][1] && a[2][2]){
for(int i = 0; i <= 2; ++i){
for(int j = 0; j <= 2; ++j){
if(!a[i][j] || i == j) continue;
for(int k = 0; k <= 2; ++k){
if(!a[j][k] || j == k || i == k) continue;
puts("YES");
for(int l = 1; l <= n; ++l) printf("%c",i+'a');
for(int l = 1; l <= n; ++l) printf("%c",j+'a');
for(int l = 1; l <= n; ++l) printf("%c",k+'a');
return 0;
}
}
}
}
else{
for(int i = 0; i <= 2; ++i){
for(int j = 0; j <= 2; ++j){
if(!a[i][j] || i == j) continue;
for(int k = 0; k <= 2; ++k){
if(!a[j][k] || j == k || i == k || !a[k][i]) continue;
puts("YES");
for(int l = 1; l <= n; ++l) printf("%c%c%c",i+'a',j+'a',k+'a');
return 0;
}
}
}
}
}

CF1213F Unstable String Sort

标签:图论 \(C\)

你考虑我们可以发现,排列的限制本质上是 \(s_{a_i} \leq s_{a_{i+1}} \leq s_{a_i}+1\)

其实这个建出来就可以去跑 差分约束 了(读者可以尝试一下)

我们又可以发现,因为有字母种类的限制 \(k\),但是显然我们构造了一个种类大于 \(k\) 的方案可以很容易的将种类缩减为 \(k\)

所以现在只需要让种类数量越大越好。

我们发现如果成环的话,显然环上点的种类必须相同。

最后我们缩点完了就直接跑一边 DFS 即可

code
#include<bits/stdc++.h>
using namespace std;
const int NN = 2e5 + 8;
int n,k;
struct Graph{
struct Edge{
int to,next;
}edge[NN << 1];
int head[NN],cnt;
void init(){
memset(head,-1,sizeof(head));
cnt = 1;
}
void add_edge(int u,int v){
edge[++cnt] = {v,head[u]};
head[u] = cnt;
}
}G,T;
bool vis[NN];
int sta[NN],top;
int dfn[NN],low[NN],timet;
int scc[NN],scccnt;
void tarjan(int u){
dfn[u] = low[u] = ++timet;
sta[++top] = u;vis[u] = 1;
for(int i = G.head[u]; i != -1; i = G.edge[i].next){
int v = G.edge[i].to;
if(!dfn[v]){
tarjan(v);
low[u] = min(low[u],low[v]);
}
else if(vis[v]) low[u] = min(low[u],dfn[v]);
}
if(dfn[u] == low[u]){
++scccnt;
while(sta[top+1] != u){
scc[sta[top]] = scccnt;
vis[sta[top]] = 0;
--top;
}
}
}
int du[NN];
int dis[NN];
int dismax = 0;
void tope(){
queue<int> q;
for(int i = 1; i <= scccnt; ++i){
if(du[i] == 0) q.push(i);
}
while(!q.empty()){
int u = q.front();q.pop();
for(int i = T.head[u]; i != -1; i = T.edge[i].next){
int v = T.edge[i].to;
dis[v] = max(dis[v],dis[u]+1);
if(--du[v] == 0) q.push(v);
dismax = max(dismax,dis[v]);
}
}
}
int main(){
G.init();T.init();
scanf("%d%d",&n,&k);
for(int i = 1,a,pre; i <= n; ++i){
scanf("%d",&a);
if(i != 1) G.add_edge(pre,a);
pre = a;
}
for(int i = 1,a,pre; i <= n; ++i){
scanf("%d",&a);
if(i != 1) G.add_edge(pre,a);
pre = a;
}
for(int i = 1; i <= n; ++i){
if(!dfn[i])tarjan(i);
}
for(int u = 1; u <= n; ++u){
for(int i = G.head[u]; i != -1; i = G.edge[i].next){
int v = G.edge[i].to;
if(scc[u] == scc[v]) continue;
T.add_edge(scc[u],scc[v]);
++du[scc[v]];
}
}
tope();
if(dismax < k-1){
puts("NO");
return 0;
}
puts("YES");
for(int i = 1; i <= n; ++i){
printf("%c",'a' + min(k-1,dis[scc[i]]));
}
}

CF1213G Path Queries

标签:图论 \(C^-\)| DS \(C^-\)

我们这道题显然第一步就是离线询问,从小到大加边

我们显然需要动态维护联通块的大小来维护答案

进而可以想到 带权并查集 即可

code
#include<bits/stdc++.h>
using namespace std;
const int NN = 2e5 + 8;
typedef long long ll;
int n,m;
struct E{
int u,v;
int val;
bool operator < (const E &x)const{
return val < x.val;
}
}e[NN];
int fa[NN],siz[NN],cnt;
ll ans[NN];
ll res;
int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void merge(int x,int y){
int fx = find(x),fy = find(y);
if(fx == fy) return;
res -= 1ll * siz[fx] * (siz[fx]-1) / 2;
res -= 1ll * siz[fy] * (siz[fy]-1) / 2;
fa[fx] = fy;
siz[fy] += siz[fx];
res += 1ll * siz[fy] * (siz[fy]-1) / 2;
return ;
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; ++i) fa[i] = i,siz[i] = 1;
for(int i = 1; i < n; ++i){
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].val);
}
sort(e+1,e+1+n);
int now = 1;
for(int i = 1; i <= 2e5; ++i){
for(; now <= n && e[now].val <= i; ++now){
merge(e[now].u,e[now].v);
}
ans[i] = res;
}
for(int i = 1; i <= m; ++i){
int x;
scanf("%d",&x);
printf("%lld ",ans[x]);
}
}
posted @   ricky_lin  阅读(9)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 有我 周深
有我 - 周深
00:00 / 00:00
An audio error has occurred.

作词 : 唐恬/闫光宇

作曲 : 钱雷

编曲 : 赵兆/付虹宇

制作人 : 赵兆

出品 : 共青团中央宣传部

版权 : 中国青少年新媒体协会

制作单位 : 能量悦动音乐

发行单位 : 银河方舟StarNation

出品人 : 郭峰

总监制 : 汤杰

总策划 : 钟亚楠

总统筹 : 金慧子

音乐监制 : 李天鹏/李三木

制作执行 : 张不贰/高聪怡

项目宣发 : 肖健/张国党/孙小千/戴胤/孙雯璟

音乐推广 : 代诗琪/杜思潮/马越/程铁峰/傅之豪

钢琴 : 赵兆

吉他 : 伍凌枫

贝斯 : 韩阳

鼓 : 武勇恒

合唱设计 : 赵兆

合唱 : 凡尔赛合唱团

人声录音 : 耿潇微

人声录音室 : 55TEC Studio Beijing

配唱 : 徐威@52Hz Studio (Shanghai)

混音 : 李游(小骷髅)@55TEC Studio Beijing

海报 : 格子

特别鸣谢 : 周深工作室

世界问 你是谁 来自哪 请回答

爱什么 梦什么 去何方 请回答

答案有 一百年的时光

我来自 硝烟中 课桌旁 的太阳

我来自 硝烟中 课桌旁 的太阳

他和她 宣的誓 迎的仗

来自那 燃烧的 和我一样 的年华

来自世间 一对平凡的夫妻 身旁

来自世间 一对平凡的夫妻 身旁

来自昨天 谁以青春赴万丈 理想

我是寸土 不让的 家乡啊

我是绝不 低头的 倔强啊

接过万千热血 的初衷

当有对答世界 的音量

要怎么形容明天 像我一样

要怎么形容明天 像我一样

承风骨亦有锋芒 有梦则刚

去何方 去最高 的想象

前往皓月星辰 初心不忘

那未来如何登场 有我担当

那未来如何登场 有我担当

定是你只能叫好 那种辉光

护身旁 战远方 有我啊

我的名字就是 站立的地方

Wu~

我的样子 就是 明天的模样

我是朝阳 落在乡间听书声 朗朗

我是朝阳 落在乡间听书声 朗朗

我是屏障 为谁挡一程厄运 的墙

我要一生 清澈地 爱着啊

我要长歌 领着风 踏着浪

朝着星辰大海 的方向

当有对答世界 的音量

要怎么形容明天 像我一样

要怎么形容明天 像我一样

承风骨亦有锋芒 有梦则刚

去远方 去最高 的想象

前往皓月星辰 初心不忘

那未来如何登场 有我担当

那未来如何登场 有我担当

定是你只能叫好 那种辉光

护身旁 战远方 有我啊

一生骄傲为我 站立的地方

Wu~

我的样子 就是 中国的模样

Wu~~~ Wu~~~

当炬火 去化作那道光

“谨以此歌献给一代代不负时代重托的中国青年”

“谨以此歌献给一代代不负时代重托的中国青年”