T1 心有灵犀 (cooperate)

题目大意

给你一个不超过 \(10^9\) 的数字 \(n\) 和一个交换次数上限 \(k\),

每次操作对这个 数字 \(n\) 的其中两位进行交换,

比如 201 可以换成 102,

让你进行 \(k\) 次操作,求出交换后最大的数字和最小的数字的差的绝对值

思路

  • 某一位的数字可以和它本身进行交换
  • 交换的数字不可以有前导零(即第一位不可以是 \(0\))

解法

  • 数据不超过 \(10^9\) ,可以考虑将每一位进行拆分
  • 还记得我们学深搜时的全排列吗?
  • 暴力枚举在 \(k\) 次交换下的广义全排列,挨个比较得到 \(max \ min\) ,相见即可

误导

  • 这道题的关键是大家很容易误以为是贪心,而一般贪心是错的
  • 举例:
    • \(k=2\) 时的 \(970979\),贪心求出最大值是 \(999077\),
    • 但实际上可以达到的最大值是 \(999770\) 。
    • 所以这题不是个简单的贪心。

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <string.h>
using namespace std;
#define int long long const int manx=1e6+10;
const int mamx = 1e6 + 11;
const int mod = 2123400401301379571;
const int inf = 0x3f3f3f3f; inline int read() {
char c = getchar(); int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int t,n,m,now[manx],cnt,maxn,minx,k;
int a[manx],b[manx],js,bz;
void dfs_min(int k,int cnt){
if(k <= 0 || cnt >= js){
int s = 0;
for(int i = 1;i <= js;i++)
s = s*10 + b[i];
if(s > bz) minx = min(s,minx);//s-->minx,100 --> 0
/*
bz : 标准
含义是当前这个序列组成的数必须比 10^(js-1)大,(防止前导零)
*/
return;
}
for(int i = cnt + 1;i <= js; i++){
if(b[i] <= b[cnt]){
swap(b[i],b[cnt]);
dfs_min(k-1,cnt+1);
swap(b[i],b[cnt]);//回溯
}
}
dfs_min(k,cnt+1);//当前这个数即为最小数,直接搜索下一位
}
void dfs_max(int k,int cnt){
if(k <= 0 || cnt >= js){
int s = 0;
for(int i = 1;i <= js;i++)
s = s*10 + a[i];
maxn = max(maxn,s);
return;
}
for(int i = cnt + 1;i <= js; i++){
if(a[i] >= a[cnt]){
swap(a[i],a[cnt]);
dfs_max(k-1,cnt+1);
swap(a[i],a[cnt]);
}
}
dfs_max(k,cnt+1);//原理同上
}
void solve(){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(now,0,sizeof(now));
cnt = js = 0;
minx = inf, maxn = 0;
n = read();k = read();
while(n){
now[++cnt] = n%10; //倒序去位数
n = n/10;
}
bz = 1;
for(int i = cnt;i >= 1; i--){
a[++js] = now[i],b[js] = now[i];//不可以连等吗
bz *= 10;
}
bz = bz/10;//位数是(js-1)
dfs_max(k,1),dfs_min(k,1);
cout<< maxn - minx << '\n';
}
signed main(){
t = read();
while(t--) solve();
return 0;
}

T2 不服来战 (challenge.cpp)

题面

  • 你有一列 \(N\) 盏灯,初始时有些是开的,有些是关的, 每盏灯有各自的权值。
  • 每次操作你可以改变任意连续 \(K\) 盏灯的开关状态。
  • 你可以操作任意多次,求最终最大的亮着的灯的权值和

解法

优化

  • 再稍作分析,不难发现,如果一组内“初始时是关的”的灯为偶数个,那么我们可以 做到只把它们全部打开,也就是说打开了这一组所有的灯
  • 如果一组内“初始时是关的” 的灯为奇数个,这个时候我们不能把所有的灯都打开,只好作出让步,选择放弃亮度最小的那盏灯。每一组都如此处理,最后加起来。

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll; const int manx=1e6+10;
const int mamx = 1e6 + 11;
const ll mod = 2123400401301379571;
const int inf = 0x3f3f3f3f; inline int read() {
char c = getchar(); int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int T ,a[manx] ,n ,k ,ans;
bool pd[manx];
inline int Check(int n ,int k ,bool pd[] ,int a[]){
int ret = 0;
for(int i = 1;i <= k;i ++){
int cnt = 0,minx = inf;
for(int j = i; j <= n; j+=k){
ret += a[j];
minx = min(minx ,a[j]);
if(pd[j] == 0) cnt++;//记录零的个数
}
if(cnt % 2 != 0) ret -= minx;
}
return ret;
}
int main(){
T = read();
while(T--){
ans = 0;
n = read(); k = read();
for(int i = 1;i <= n; i++) pd[i] = read();
for(int i = 1;i <= n; i++) a[i] = read();
if(k == 1){
for(int i =1;i <= n; i++) ans += a[i];
}else{
ans = Check(n ,k ,pd ,a);
/*
两种情况,第一个是不翻转1-k,得到的最小值,
第二个是翻转后得到的最小值,
(因为就两种情况前 1-k 翻与不翻)
*/
for(int i = 1;i <= k; i++) pd[i] ^= 1;//pd [i] ---> pd [k] 100 --> 0
ans = max(ans,Check(n ,k ,pd ,a));
}
cout<<ans<<'\n';
}
return 0;
}

T3 铁路网络 (network.cpp)

题面

  • 给你一棵有根树,每条边有边权。
  • 实现两种操作:
  • \(a\). 给某一条路径上所 有边的权值加上一个数;
  • \(b\). 询问某棵子树内所有点对的距离和。

思路

  • 显然可以用树链剖分进行操作,和线段树进行维护,

  • 路径修改,求子树间两点路径的总和(不是子树查询)

  • 值得注意的是,点权边权,操作路径修改是要注意 \(dfn[u]\) 的位置,避免多加,或少加

  • 不妨设点 \(x\) 与它的父亲 \(fa[x]\) 相连的边的权值为 \(p[x]\),

  • 考虑 \(p[x]\) 会对那些点对产生贡献?

  • 显然是经过 \(x——fa[x]\) 这条边的那些点对。记 \(size_[x]\) 为以 \(x\) 为根的子树的大小。

  • 则经过 \(x——fa[x]\) 的点对有 \(size_[x]×(size_[i] – size_[x])\) 对

  • 于是,子树 \(i\) 内的点 \(x\) 的贡献

  • \[p[x]\times size_[x]\times size_[i] - p[x] \times size_[x]^2
    \]
  • \[\begin{alignedat}{3}
    \sum_{i=1}p[x]\times size_[x]\times size_[i] - p[x] \times size_[x]^2\\
    =size_[i]\times \sum_{i=1}(p[i]\times size_[i])-\sum_{i=1}(p[i]\times size_[i]^2)\\
    \end{alignedat}
    \]

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
#define ll long long const int manx = 1e6;
const int mod = 2123400401301379571;
const int inf = 0x3f3f3f3f; inline int read(){
char c = getchar(); int x = 0, f = 1;
for( ;!isdigit(c);c = getchar()) if(c == '-') f = -1;
for( ;isdigit(c);c = getchar()) x = x*10 + (c^48);
return x * f;
}
struct node{
int v,nxt;
}e[manx];
int head[manx],cnt,n,m,dep[manx],fa[manx],size_[manx],val[manx],pre[manx],tp[manx],dfn[manx],hson[manx];
int js,sigma1,sigma2;
inline void add(int u,int v){
e[++cnt].nxt = head[u];
e[cnt].v = v;
head[u] = cnt;
} namespace Tree{
#define ls i<<1
#define rs i<<1|1
struct tree{
int l;int r;
ll sum,lazy;
}tr[manx<<3];
inline void up(int i){
tr[i].sum = tr[ls].sum + tr[rs].sum ;
}
inline void down(int i){
if(tr[i].lazy){
ll x = tr[i].lazy ;
tr[ls].sum += (tr[ls].r - tr[ls].l +1)*x;
tr[rs].sum += (tr[rs].r - tr[rs].l +1)*x;
tr[ls].lazy += x;
tr[rs].lazy += x;
tr[i].lazy = 0;
}
}
inline void build(int i,int l,int r){
tr[i].l = l;tr[i].r = r;
if(l == r){
tr[i].sum = val[pre[l]];
return ;
}
int mid = (l + r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
up(i);
}
inline void add(int i,int l,int r,int w){
if(tr[i].l >= l && tr[i].r <= r){
tr[i].sum += (tr[i].r - tr[i].l +1)*w;
tr[i].lazy += w;
return;
}
down(i);
int mid=(tr[i].l +tr[i].r )>>1;
if(mid >= r)add(ls,l,r,w);
else if(mid < l)add(rs,l,r,w);
else add(ls,l,mid,w),add(rs,mid+1,r,w);
up(i);
}
inline ll only_query(int i,int u){
if(tr[i].l == tr[i].r ){
return tr[i].sum ;
}
down(i);
int mid=(tr[i].l +tr[i].r )>>1;
if(mid >= u) return only_query(ls,u);
else if(mid < u) return only_query(rs,u);
}
inline ll query(int i,int l,int r){
if(tr[i].l >= l && tr[i].r <= r){
return tr[i].sum ;
}
down(i);
int mid=(tr[i].l +tr[i].r )>>1;
if(mid >= r)return query(ls,l,r);
else if(mid < l)return query(rs,l,r);
return query(ls,l,mid)+query(rs,mid+1,r);
}
}
namespace Node{
inline void dfs1(int u,int pre,int d){
fa[u] = pre; dep[u] = d;size_[u] = 1;
for(int i = head[u]; i;i = e[i].nxt){
int v = e[i].v ;
if(v != pre){
dfs1(v,u,d+1);
size_[u] += size_[v];
if(!hson[u] || size_[hson[u]] < size_[v]){
hson[u] = v;
}
}
}
}
inline void dfs2(int u,int top){
tp[u] = top;
dfn[u] = ++js;
pre[js] = u;
if(!hson[u])return;
dfs2(hson[u],top);
for(int i = head[u];i;i = e[i].nxt ){
int v = e[i].v ;
if(v != fa[u] && v != hson[u]){
dfs2(v,v);
}
}
}
inline void add(int u,int v,int w){
while(tp[u] != tp[v]){
if(dep[tp[u]] < dep[tp[v]])swap(u,v);
Tree::add(1,dfn[tp[u]],dfn[u],w);
u = fa[tp[u]];
}
if(dep[u]>dep[v])swap(u,v);
Tree::add(1,dfn[u] + 1,dfn[v],w);
}
inline void query(int u){
for(int i = head[u]; i; i = e[i].nxt ){
int v = e[i].v ;
if(v != fa[u]){
Node::query(v);
int s = Tree::only_query(1,dfn[v]);
// cout<<s<<" "<<v<<endl;
sigma1 += (s * size_[v]);
sigma2 += (s * size_[v] * size_[v]);
}
}
return;
}
}
char a[9];
int main(){
//freopen("pp.in","r",stdin);
//freopen("network.out","w",stdout);
n = read();m = read();
for(int i = 1;i < n; i++){
int x = read(), y = read();
val[i+1] = y;
add(i+1,x);
add(x,i+1);
}
Node::dfs1(1,0,1),Node::dfs2(1,1),Tree::build(1,1,n);
for(int i = 1;i <= m; i++){
cin>>a;
ll ans = 0;
ll fan = 0;
int x,y,z;
if(a[0] == 'I'){
x = read(); y = read(); z = read();
Node::add(x,y,z);
}else{
x = read();
sigma1 = 0;
sigma2 = 0;
Node::query(x);
cout<<size_[x] * sigma1 - sigma2 <<endl;
}
}
return 0;
}

感谢观看

11.15 gryz校测(题解分析报告)的更多相关文章

  1. 2017.12.10《“剑锋OI”普及组多校联盟系列赛(14)#Sooke#Kornal 的课余时间 》分析报告

    报告内容如下 - - [导语] ------ 太晚了,时间也紧,一切尽量从简吧 PS:本文题目来自剑锋OI 所以废话也不多说,进入正题吧,代码直接跟在题目后边儿,主要分析在代码前,次要的就写在代码后面 ...

  2. 精通Web Analytics 2.0 (11) 第九章: 新兴分析—社交,移动和视频

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第九章: 新兴分析-社交,移动和视频 网络在过去几年中发生了不可思议的发展变化:从单向对话到双向对话的转变; 由视频,Ajax和 ...

  3. [FreeBuff]Trojan.Miner.gbq挖矿病毒分析报告

    Trojan.Miner.gbq挖矿病毒分析报告 https://www.freebuf.com/articles/network/196594.html 竟然还有端口转发... 这哥们.. 江民安全 ...

  4. 转:国内Top500Android应用分析报告

    转自:https://mp.weixin.qq.com/s?__biz=MzA5OTMxMjQzMw==&mid=2648112527&idx=1&sn=b23c1b5f3e3 ...

  5. Android木马病毒com.schemedroid的分析报告

    某安全公司移动病毒分析报告的面试题目,该病毒样本的代码量比较大,最大的分析障碍是该病毒样本的类名称和类方法名称以及类成员变量的名称被混淆为无法辨认的特殊字符,每个被分析的类中所有的字符串都被加密处理了 ...

  6. Alpha阶段事后分析报告

    每个团队编写一个事后分析报告,对于团队在Alpha阶段的工作做一个总结. 请在2016年11月24日上课之前根据下述博客中的模板总结前一阶段的工作,发表在团队博客上,并在课上的事后分析会上进行汇报,并 ...

  7. Google发布SSLv3漏洞简要分析报告

    今天上午,Google发布了一份关于SSLv3漏洞的简要分析报告.根据Google的说法,该漏洞贯穿于所有的SSLv3版本中,利用该漏洞,黑客可以通过中间人攻击等类似的方式(只要劫持到的数据加密两端均 ...

  8. 使用AES加密的勒索类软件分析报告

    报告名称:  某勒索类软件分析报告    作者:        李东 报告更新日期: 样本发现日期: 样本类型: 样本文件大小/被感染文件变化长度: 样本文件MD5 校验值: da4ab5e31793 ...

  9. 测试计划&性能测试分析报告模板(仅供参考)

    一.测试计划 1. 引言 1.1  编写目的 2. 参考文档 3. 测试目的 4. 测试范围 4.1  测试对象 4.2  需要测试的特性 4.3  无需测试的特性 5. 测试启动与结束准则 5.1  ...

随机推荐

  1. mysql组合索引之最左原则

    为什么在单列索引的基础上还需要组合索引? select product_id from orders where order_id in (123, 312, 223, 132, 224); 我们当然 ...

  2. 音视频入门-19-使用giflib处理GIF图片

    * 音视频入门文章目录 * GIFLIB The GIFLIB project 上一篇 [手动生成一张GIF图片], 自己生成了一张 GIF 动态图 rainbow.gif. 下面,使用 GIFLIB ...

  3. Task1:知识图谱介绍(1天)

    一.知识图谱简介 "知识图谱本质上是语义网络(Semantic Network)的知识库".但这有点抽象,所以换个角度,从实际应用的角度出发其实可以简单地把知识图谱理解成多关系图( ...

  4. 解放双手,markdown文章神器,Typora+PicGo+七牛云图床实现自动上传图片

    本文主要分享使用Typora作为Markdown编辑器,PicGo为上传图片工具,使用七牛云做存储来解放双手实现图片的自动化上传与管理.提高写作效率,提升逼格.用过 Markdown 的朋友一定会深深 ...

  5. 浅谈 Checkbox Group 的双向数据绑定

    前言 不曾想在忙碌的工作面前,写一篇技术博客也成了奢求. Checkbox 作为表单中最常见的一类元素,使用方式分为单值和多值,其中单值的绑定很简单,就是 true 和 false,但是多值(Chec ...

  6. 拍摄、剪辑vlog的思路

    这篇文章是看了很多狂阿弥_ 的作品后 产生的一些小小总结.这些技法只是锦上添花,阿弥作品真正好的地方在于他细腻的情感,真实的对白,和打动人心的满分作文. 优秀的Vlog ,在于它和观众产生的情感共鸣. ...

  7. (二)数据源处理4-excel部分封装及数据转换

    excel02.py # -*- coding: utf-8 -*-#@File :excel_oper_02.py#@Auth : wwd#@Time : 2020/12/7 8:16 下午impo ...

  8. 【ORA】ora-39700解决

  9. [WPF] 在单元测试中使用 Prism 的 EventAggregator,订阅到 ThreadOption.UIThread 会报错

    1. 问题 [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { ContainerLocator ...

  10. 07--Docker安装Redis

    1.拉取redis:3.2 docker pull redis:3.2 2.创建redis容器 docker run -p 6379:6379 -v /zhengcj/myredis/data:/da ...