\[だから妄想感傷代償連盟
\]
\[愛を懐いて理想を叫んだ
\]
\[行き場のない愚者のメロディー
\]
\[再挑戦•転生•テレポーテーション
\]
\[何回だって 重ねて逝くんだ
\]
\[終わりなき愛の随に さあ
\]
\[愛や厭...
\]

提要:打比赛的时候这东西在我脑子里放了四个小时

A.黎明与萤火

容易想到无解的判断:每次删除节点都会至少导致减少 \(4\) 的总度数,且减少的度数总会是 \(4\) 的倍数,因此总度数不为 \(4\) 的倍数的即为无解,搜一遍即可.

随后输出方案数. 考虑到叶节点只能被其父节点删除导致删除,因此可以先从上到下删除叶节点的父节点,再从上到下删除叶节点即可. 实际实现的时候比较简单,两遍搜即可.

复杂度 \(O(N)\)

#include<bits/stdc++.h>
using namespace std;
int n;
vector<int>e[200001];
vector<int>son[200001];
int degree[200001];
bool vis[200001];
int fa[200001];
void dfs(int now,int last){
fa[now]=last;
son[last].push_back(now);
for(int i:e[now]){
if(i!=last) dfs(i,now);
}
}
void print1(int now){
if(vis[now]){
for(int i:son[now]) print1(i);
return;
}
for(int i:son[now]){
print1(i);
}
if(degree[now]%2==0){
vis[now]=true;
printf("%d\n",now);
degree[fa[now]]--;
for(int i:son[now]){
degree[i]--;
}
}
}
void print2(int now){
if(vis[now]){
for(int i:son[now]) print2(i);
return;
}
if(degree[now]%2==0){
vis[now]=true;
printf("%d\n",now);
degree[fa[now]]--;
for(int i:son[now]){
degree[i]--;
}
}
for(int i:son[now]){
print2(i);
}
}
int main(){
// freopen("test.in","r",stdin);
// freopen("test.out","w",stdout);
scanf("%d",&n);int root=0;
for(int i=1;i<=n;++i){
int x;scanf("%d",&x);
if(x){
e[i].push_back(x);
e[x].push_back(i);
}
}
for(int i=1;i<=n;++i){
if(e[i].size()%2==0){
root=i;
break;
}
}
dfs(root,0);
int res=0;
for(int i=1;i<=n;++i){
res+=son[i].size();
degree[i]=son[i].size()+1;
}
degree[root]--;
if((res+n-1)%4!=0){
cout<<"NO"<<'\n';
return 0;
}
cout<<"YES"<<'\n';
print1(root);
print2(root);
}

B.Darling Dance

这个 Darling Dance 曲绘怎么一股兔子洞味,但是完全不是同一个 P 主

好题

考虑先找出哪些边会在一些节点到 \(1\) 的最短路上,可以发现这些边会构成一颗以 \(1\) 为根的树

证明:在最短路上走环一定不优,因此不存在环,故为树

又因为该树有全部的 \(n\) 个节点,可以推至树上共 \(n-1\) 条边.

因此当 \(k\ge n-1\) 时,直接全选即可.

否则,考虑到不选边缘的边可以使答案更优,直接从根节点搜下来即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,k;
struct edge{
int to,w,id;
};
vector<edge>e[300001];
int dis[300001];
bool vis[300001];
int pre[300001];
vector<int>e2[300001];
struct node{
int id,dis;
bool operator <(const node &A)const{
return dis>A.dis;
}
};
priority_queue<node>p;
bool istree[300001];
void dij(int s){
memset(vis,0,sizeof vis);
memset(dis,0x3f,sizeof dis);
dis[s]=0;
p.push({s,dis[s]});
while(!p.empty()){
node u=p.top();
p.pop();
if(vis[u.id]) continue;
istree[pre[u.id]]=true;
vis[u.id]=true;
for(edge i:e[u.id]){
if(!vis[i.to]){
if(dis[i.to]>dis[u.id]+i.w){
dis[i.to]=dis[u.id]+i.w;
p.push({i.to,dis[i.to]});
pre[i.to]=i.id;
}
}
}
}
}
vector<int>ans;
void dfs(int now,int last){
if((int)ans.size()==k) return;
// cout<<"dfs "<<now<<" "<<last<<endl;
for(edge i:e[now]){
if((int)ans.size()==k) return;
if(i.to!=last and istree[i.id]){
ans.push_back(i.id);
dfs(i.to,now);
}
}
}
signed main(){
// freopen("T2.in","r",stdin);
// freopen("out.out","w",stdout);
scanf("%lld %lld %lld",&n,&m,&k);
for(int i=1;i<=m;++i){
int x,y,z;
scanf("%lld %lld %lld",&x,&y,&z);
e[x].push_back({y,z,i});
e[y].push_back({x,z,i});
}
dij(1);
// for(int i=1;i<=m;++i){
// cout<<i<<" "<<istree[i]<<endl;
// }
dfs(1,0);
cout<<ans.size()<<endl;
for(int i:ans){
cout<<i<<" ";
}
}

C.Non-breath oblige

可以把操作离线下来搞扫描线,但是我不会,所以学了另一种方法

首先可以想到操作能直接用暴力线段树维护

1 操作就相当于两次单点查询于修改

2 操作是区间赋值

3 操作是单点查询

因此可以直接建线段树,但是复杂度太高,考虑优化。

注意到可以直接放弃暴力修改,直接记下操作一改变后的 \(pos\),然后每次查询直接跳到对应区间查询,这是一种可行的思路,提议转化成询问在 \(l\) 到 \(r\) 之间 \(type_i=3\) 且 \(pos_i\geq l\) 的所有 \(i\) 的 \(val_i\) 之和。

接下来可以上一颗树状数组,维护操作变化,把询问按 \(l\) 降序排序,然后按 \(pos\) 降序依次把 \(val\) 加入树状数组,拿双指针搞,询问的时候直接查 \(query(r)-query(l-1)\) 就行了。

#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T& x){
x=0;bool sym=0;char c=getchar();
while(!isdigit(c)){sym^=(c=='-');c=getchar();}
while(isdigit(c)){x=x*10+c-48;c=getchar();}
if(sym)x=-x;
}
template<size_t N>
inline void read(char (&str)[N]){
size_t n=0;char c=getchar();
while(n<N-1&&!isspace(c)){str[n]=c;c=getchar();++n;}
str[n]=0;
}
template<typename T,size_t N>
inline void read(T (&a)[N],int range=N){
for(int i=1;i<=range;++i){read(a[i]);}
}
template<typename T,typename... Args>
inline void read(T& x,Args&... args){
read(x);read(args...);
}
template<typename T,typename T2>
inline void readarray(T& x,T2& args){
read(x);read(args,x);
}
template<typename func,typename... Args>
inline void readact(int x,function<func>fu,Args&... args){
for(int i=1;i<=x;++i){
read(args...);
fu(args...);
}
}
#define inread(x) int (x);read(x)
inline void write(int A){if(A<0){putchar('-');A=-A;}if(A>9){write(A/10);}putchar(A%10+'0');}
inline void write(long long A){if(A<0){putchar('-');A=-A;}if(A>9){write(A/10);}putchar(A%10+'0');}
inline void write(char A){putchar(A);}
int n,m,Q;
struct tree{
int l,r;
int w;
}t[4000001];
#define tol (id*2)
#define tor (id*2+1)
#define mid(l,r) mid=((l)+(r))/2
inline void pushdown(int id){
if(t[id].w){
t[tol].w=t[tor].w=t[id].w;
t[id].w=0;
}
}
void build(int id,int l,int r){
t[id].l=l;t[id].r=r;
if(l==r){
t[id].w=0;
return;
}
int mid(l,r);
build(tol,l,mid);
build(tor,mid+1,r);
}
void change(int id,int l,int r,int val){
// cout<<id<<" "<<l<<" "<<r<<" "<<t[id].l<<" "<<t[id].r<<" "<<val<<endl;
if(l<=t[id].l and t[id].r<=r){
t[id].w=val;
return;
}
pushdown(id);
if(l<=t[tol].r) change(tol,l,r,val);
if(t[tor].l<=r) change(tor,l,r,val);
}
int ask(int id,int pos){
if(t[id].l==t[id].r or t[id].w) return t[id].w;
int mid(t[id].l,t[id].r);
if(pos<=mid) return ask(tol,pos);
else return ask(tor,pos);
}
long long sum[1000001];
auto lowbit=[](int x){return x&(-x);};
inline void add(int x,int val){
if(!x) return;
while(x<=m){
sum[x]+=val;
x+=lowbit(x);
}
}
inline long long ask(int x){
if(x<1) return 0;
long long ans=0;
while(x){
ans+=sum[x];
x-=lowbit(x);
}
return ans;
}
struct area{
int l,r;
};
vector<area>q[1000001];
long long ans[1000001];
struct operation{
int op,x,y,val;
}o[1000001];
int main(){
read(n,m,Q);
build(1,1,n);
bool has2=false;
for(int i=1;i<=m;++i){
read(o[i].op);
if(o[i].op==1){
read(o[i].x,o[i].y);
int hx=ask(1,o[i].x),
hy=ask(1,o[i].y);
change(1,o[i].x,o[i].x,hy);
change(1,o[i].y,o[i].y,hx);
}
else if(o[i].op==2){
has2=true;
read(o[i].x,o[i].y,o[i].val);
change(1,o[i].x,o[i].y,i);
}
else{
read(o[i].x);
o[i].y=ask(1,o[i].x);
}
}
if(!has2){
for(int i=1;i<=Q;++i){
write(0);
putchar('\n');
}
return 0;
}
for(int i=1;i<=Q;++i){
inread(l);inread(r);
q[r].push_back({l,i});
}
// cout<<"?"<<endl;
for(int i=1;i<=m;++i){
// cout<<i<<" "<<m<<endl;
if(o[i].op==3){
add(o[i].y,o[o[i].y].val);
// cout<<i<<" "<<m<<"?"<<endl;
}
for(area j:q[i]){
ans[j.r]=ask(i)-ask(j.l-1);
}
}
// cout<<"?"<<endl;
for(int i=1;i<=Q;++i){
write(ans[i]);
putchar('\n');
}
}

暑集假训SCP提高拟模21的更多相关文章

  1. 【libreOJ模板】并查集(输入挂,取模与find优化)

    1.了解了各种输入挂性orz,找到了一个合适的 2.find用while写能快一倍,并且能被数据卡掉 3.取模只能快十几毫秒,但也能被数据卡掉 取模find双优化是1997mm过的 再加一个性价比较高 ...

  2. C基础的练习集及测试答案(提高题)

    提高题:1.编写程序,随机生成一个1~10内的数,让对方猜3次.如果3次内能猜中则输出“恭喜你”:若3次内猜不中则输出正确答案.C语言中提供生成随机数的函数rand()用法:①所需头文件:#inclu ...

  3. Redis集群数据没法拆分时的搭建策略

    在上一篇文章中,针对服务器单点.单例.单机存在的问题: 单点故障 容量有限 可支持的连接有限(性能不足) 提出了解决的办法:根据AKF原则搭建集群,大意是先X轴拆分,创建单机的镜像,组成主主.主备.主 ...

  4. linux 集群及lvs

    集群及LVS 集群: 一组通过高速网络互联的计算机组,并以单一系统的模式加以管理 价格很多服务器集中起来,提供同一种服务,在客户端看起来就像只有一个服务器 可以在付出较低成本的情况下获得在性能,可靠性 ...

  5. MongoDB-副本集搭建与管理

    目录 MongoDB 副本集 一.副本集概念 二.副本集部署 三 .副本集维护 四.注意事项 MongoDB 副本集 一.副本集概念 单节点的 MongoDB 在数据的安全和冗余方面是比较低的,在生产 ...

  6. 基于Hadoop2.5.0的集群搭建

    http://download.csdn.net/download/yameing/8011891 一. 规划 1.  准备安装包 JDK:http://download.oracle.com/otn ...

  7. 006.MongoDB副本集

    一 MongoDB 复制(副本集) 1.1 复制概述 MongoDB复制是将数据同步在多个服务器的过程. 复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的 ...

  8. Tika结合Tesseract-OCR 实现光学汉字识别(简体、宋体的识别率百分之百)—附Java源码、测试数据和训练集下载地址

     OCR(Optical character recognition) —— 光学字符识别,是图像处理的一个重要分支,中文的识别具有一定挑战性,特别是手写体和草书的识别,是重要和热门的科学研究方向.可 ...

  9. 老司机带你玩转面试(5):Redis 集群模式 Redis Cluster

    前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...

  10. K8s二进制部署单节点 etcd集群,flannel网络配置 ——锥刺股

    K8s 二进制部署单节点 master    --锥刺股 k8s集群搭建: etcd集群 flannel网络插件 搭建master组件 搭建node组件 1.部署etcd集群 2.Flannel 网络 ...

随机推荐

  1. C# 一维数组与二维数组相互转换

    class Program { static void Main(string[] args) { double[] a = { 1, 2, 3, 4, 5, 6 }; double[,] b = R ...

  2. ABC349

    A link 其实,有人赢比赛,就有人输比赛,一加一减,不管进行多少场比赛,最后所有人的分数和一定是\(0\). 那么知道\(n-1\)个人的分数和,就可以知道第\(n\)个人的了. 点击查看代码 # ...

  3. RHCA rh442 007 hugetlbfs strace命令追踪 脏页设置 内存分配

    内存管理 虚拟内存 --- 物理内存 应用程序申请虚拟内存 --- RAM + SWAP (真正主板上的设备) 他们之间有一张映射表 page table 页表 PTE: 页表条目 虚拟内存和物理内存 ...

  4. 【Vue】Re01 理论概念和入门上手

    一.Vue概述 什么是渐进式?1.把Vue作应用的一部分嵌套项目中2.如果完全抛弃其他组件和框架,Vue又具有丰富的生态和库莱支持3.Core + Router + VueX 满足项目绝大多数的需求- ...

  5. nvidia官方AI框架软件的命令行操作接口 —— NVIDIA GPU Cloud (NGC) CLI

    NVIDIA GPU Cloud (NGC) CLI 安装介绍地址: https://org.ngc.nvidia.com/setup/installers/cli 安装好后需要输入自己的NVIDIA ...

  6. 第四范式开源强化学习框架——OpenRL

    维护者信息: 知乎地址: https://www.zhihu.com/people/huangshiyu.me 个人主页: http://tartrl.cn/people/huangshiyu/ Gi ...

  7. MindSpore1.3.0 GPU pip方式安装 —— Ubuntu18.04系统 (最终安装结果为成功)需要管理员权限,sudo安装

    官网地址: https://www.mindspore.cn/install =========================================================== 安 ...

  8. 结合实例看 maven 传递依赖与优先级,难顶也得上丫

    开心一刻 想买摩托车了,但是钱不够,想找老爸借点 我:老爸,我想买一辆摩托车,上下班也方便 老爸:你表哥上个月骑摩托车摔走了,你不知道?还要买摩托车? 我:对不起,我不买了 老板:就是啊,骑你表哥那辆 ...

  9. 11-canvas绘制折线图

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...

  10. SMU Spring 2023 Contest Round 5(2023 (ICPC) Jiangxi Provincial Contest -- Official Contest)

    题目链接 Problem A. Drill Wood to Make Fire S * V >= n即可 #include<bits/stdc++.h> #define int lo ...