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

ricky_lin

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

【题解】CF1710 合集

CF1710A Color the Picture

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

典型的有图有真相,嘻嘻(抽风了?

显然有一个结论,我们颜色要么一行一行天,要么一列一列填。

并且填进去的颜色必须不少于两行/列

然后就是记一个 ans 和 一个 over 表示如果每个颜色都两行/列填进去能填的最多列数,以及两行/列填进去后还能填多少行/列

最后就按行/列填进去判断一下即可

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int NN = 1e5 + 8;
int T;
int n,m,k;
int a[NN];
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&k);
ll ans = 0,over = 0;
for(int i = 1; i <= k; ++i){
scanf("%d",&a[i]);
ans += a[i] / n >= 2 ? 2 : 0;
over += a[i] / n >= 2 ? (a[i]/n-2) : 0;
}
if(ans == m){puts("Yes");continue;}
if(ans >= m && ((ans&1) == (m&1))){puts("Yes");continue;}
if(ans + over >= m && over){puts("Yes");continue;}
ans = 0;over = 0;
for(int i = 1; i <= k; ++i){
ans += a[i] / m >= 2 ? 2 : 0;
over += a[i] / m >= 2 ? (a[i]/m-2) : 0;
}
if(ans == n){puts("Yes");continue;}
if(ans >= n && ((ans&1) == (n&1))){puts("Yes");continue;}
if(ans + over >= n && over){puts("Yes");continue;}
puts("No");
}
}

CF1710B Rain

标签:DS \(C\) | 思维题 \(C^+\)

考虑我的方法是预处理 \(O(n\log n)\),最后求答案 \(O(n)\)

考虑我们显然可以先从左到右扫一遍,对于每一个 \(x_i\) 记录它左边的下雨对于它的雨水的深度产生的影响

然后这显然是很好维护的,就是记录当前点的水的深度影响和影响当前点的下雨天的数量,用数学语言表示就是记录当前点的点值和斜率

然后我们需要用一个小根堆记录最近的和 \(x\) 轴的交点,方便将直线退出影响,然后 \(x_i\) 的右边的下雨的影响也可以类比

最后求答案,显然可以找出所有的需要减去的位置和高度,显然我们可以将位置为 \(x\) 高度为 \(h\) 的需求抽象成 \([x-h,x+h]\) 的区间

最后就是判断去掉某一天的下雨的对应的区间能否包含所有区间,这就是维护所有需求区间的最左边和最右边 \(O(n)\) 扫一遍,然后就可以对每个询问 \(O(1)\) 求解了。

考虑代码里面后面的需求区间的最左端点和最右端点的求解有一点麻烦,希望能看懂 QWQ。

code:

#include<bits/stdc++.h>
using namespace std;
const int NN = 2e5 + 8;
typedef long long ll;
int n,m;
struct Rep{
ll x,p;
int num;
bool operator < (const Rep &A)const{
return x < A.x;
}
}a[NN],b[NN];
int top;
priority_queue<ll,vector<ll>,greater<ll> > Q;
priority_queue<ll> R;
bool ans[NN];
bool res[NN];
ll f[NN];
void solve(){
memset(f,0,sizeof(f));top = 0;
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; ++i)
scanf("%lld%lld",&a[i].x,&a[i].p),a[i].num = i,ans[i] = 1;
sort(a+1,a+1+n);
ll now = 0,cnt = 0;
while(!Q.empty())Q.pop();
for(int i = 1; i <= n; ++i){
while(!Q.empty() && Q.top() <= a[i].x){
now -= Q.top() - a[i-1].x;
--cnt;
Q.pop();
}
if(i != 1) now -= (a[i].x - a[i-1].x) * cnt;
++cnt;
now += a[i].p;
Q.push(a[i].x+a[i].p);
f[i] += now;
}
while(!R.empty())R.pop();
now = 0,cnt = 0;
for(int i = n; i >= 1; --i){
while(!R.empty() && R.top() >= a[i].x){
now -= a[i+1].x - R.top();
--cnt;
R.pop();
}
if(i != n) now -= (a[i+1].x - a[i].x) * cnt;
f[i] += now;
++cnt;
now += a[i].p;
R.push(a[i].x-a[i].p);
}
// for(int i = 1; i <= n; ++i){
// printf("%lld:%lld\n",a[i].x,f[i]);
// }
// puts("====================/");
for(int i = 1; i <= n; ++i){
if(f[i] > m){
b[++top] = {a[i].x,f[i]-m};
}
}
ll lmin = 1e18;
for(int i = 1,j = 1; i <= n; ++i){
while(j <= top && b[j].x <= a[i].x) lmin = min(lmin,b[j].x-b[j].p), ++j;
if(lmin < a[i].x - a[i].p) ans[i] = 0;
}
ll rmax = -1e18;
for(int i = n, j = top; i >= 1; --i){
while(j >= 1 && b[j].x >= a[i].x) rmax = max(rmax,b[j].x + b[j].p),--j;
if(rmax > a[i].x + a[i].p) ans[i] = 0;
}
for(int i = 1; i <= n; ++i){
res[a[i].num] = ans[i];
}
for(int i = 1; i <= n; ++i) printf("%d",res[i]);
puts("");
}
int main(){
int T;
scanf("%d",&T);
while(T--){
solve();
}
}

CF1710C XOR Triangle

标签:DP \(C^+\) | 数学 \(C\)

我们显然可以想到异或的性质:

  • \(a + b \geq a \oplus b\)

  • \(a + b > a \oplus b\) 当且仅当 \(a,b\) 有交集(\(a|b \neq 0\)

我们应用到这一道题目上就是:

  • 若满足 \((a\oplus b) + (b \oplus c) \geq (a \oplus c)\) 当且仅当 \((a\oplus b)\)\((b \oplus c)\) 有交

又因为我们的限制是对 \(a,b,c\) 的,而不是对 \(a\oplus b,b\oplus c,c\oplus a\) 的,所以说我们显然 数位DP 是枚举 \(a,b,c\)

我们设 \(f_{i,j,k}\) 表示前 \(i\) 位,\(j(0\sim 7)\) 表示三种亦或值相互之间有没有交,\(k(0\sim 7)\) 表示有没有顶上限(显然不同于普通的 数位DP 这里要枚举有没有顶上限,不然复杂度是假的)

转移很显然,直接记忆化搜索即可

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int NN = 2e5 + 8, MOD = 998244353;
int f[NN][8][8];
string s;
int a[NN];
inline int Calc(int i,int j,int k){
return ((i^j) & (j^k)) + (((i^k) & (j^k)) << 1) + (((i^j) & (i^k)) << 2);
}
inline int Calc2(int x,int i,int j,int k){
return (a[x] == i) + ((a[x] == j) << 1) + ((a[x] == k) << 2);
}
ll dfs(int x,int now,int up){
if(x == s.size()) return now == 7;
if(f[x][now][up] != -1) return f[x][now][up];
int ua = (up&1) ? a[x]:1, ub = (up>>1&1)?a[x]:1, uc = (up>>2&1)?a[x]:1;
ll ans = 0;
for(int i = 0; i <= ua; ++i){
for(int j = 0; j <= ub; ++j){
for(int k = 0; k <= uc; ++k){
ans = (ans + dfs(x+1,now | Calc(i,j,k),up & Calc2(x,i,j,k))) % MOD;
}
}
}
return f[x][now][up] = ans;
}
void solve(){
memset(f,-1,sizeof(f));
s = ' ' + s;
for(int i = 1; i < s.size(); ++i) a[i] = s[i] - '0';
printf("%lld\n",dfs(1,0,7));
}
int main(){
cin >> s;
solve();
}

CF1710D Recover the Tree

标签:思维题 \(B\) | 图论 \(B^-\)

一道比较好的构造题目,我们先需要从小到大去对区间排序,然后就是我们会发现

如果对于一个区间 \([l,r]\)\(l,r\) 分别在两个连通块区间之内,然后中间有 \(k\) 个连通块,我们的构造方案需要满足两个相邻的连通块之间不能直接相连(\(l,r\) 所在连通块可以直接相连,即使相邻)

所以当 \(k = 1\) 时,显然是无解的。

所以我们让 \(l\) 连向 \(r\) 左边的第一个连通块中的任意位置,\(r\) 连向剩下的其他 \(k - 1\) 个连通块即可

至于连通块的维护???并查集即可

#include<bits/stdc++.h>
using namespace std;
const int NN = 2e3 + 8;
char s[NN][NN];
int fa[NN];
void solve(){
int n;
scanf("%d",&n);
for(int i = 1; i <= n; ++i) fa[i] = i;
for(int i = 1; i <= n; ++i) scanf("%s",s[i]+i);
for(int i = 1; i <= n; ++i){
for(int j = i-1; j >= 1; --j)if(s[j][i] == '1' && fa[i] > j){
printf("%d %d\n", j, i);
if(fa[fa[i] - 1] > j)
{
printf("%d %d\n", j, fa[i] - 1);
for(int k = fa[fa[i] - 1] - 1; k > j; --k) if(fa[k] == k) printf("%d %d\n",k,i);
}
for(int k = j; k <= i; ++k) fa[k] = fa[j];
}
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
solve();
}
}
posted @   ricky_lin  阅读(29)  评论(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~~~

当炬火 去化作那道光

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

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