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. Windows 64位下安装Redis 以及 可视化工具Redis Desktop Manager的安装和使用

    二.下载Windows版本的Redis 由于现在官网上只提供Linux版本的下载,所以我们只能在Github上下载Windows版本的Redis Windows版本的Redis下载地址:https:/ ...

  2. ExecutionListener,TaskListener流程监听 和任务监听

    1.ExecutionListener 流程实例的启动和结束. 选中一条连线. 节点的开始和结束. 网关的开始和结束. 中间事件的开始和结束. 开始时间结束或结束事件开始. 2.TaskListene ...

  3. [LeetCode]92. Reverse Linked List II反转部分链表

    /* 重点还是反转链表 思路就是中间的反转,然后两头接上 */ public ListNode reverseBetween(ListNode head, int m, int n) { if (he ...

  4. [Machine Learning] 单变量线性回归(Linear Regression with One Variable) - 线性回归-代价函数-梯度下降法-学习率

    单变量线性回归(Linear Regression with One Variable) 什么是线性回归?线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方 ...

  5. 使用ThreadLocal

    使用ThreadLocal 阅读: 135212 多线程是Java实现多任务的基础,Thread对象代表一个线程,我们可以在代码中调用Thread.currentThread()获取当前线程.例如,打 ...

  6. k8s之DNS服务器搭建

    一.导读 在使用k8s部署springboot+redis简单应用这篇文章中,spring boot连接redis是直接使用的IP连接,那么可不可以直接使用服务名称进行连接呢?答案是可以的,这就是k8 ...

  7. java面向对象的一些知识

    (1)this和super关键字的用法 this表示调用本类实例方法和成员变量,this引用就是对一个对象的引用,如this.name  表示本类成员变量name,静态方法中不能使用this关键字. ...

  8. 【老孟Flutter】Flutter 中与平台相关的生命周期

    老孟导读:关于生命周期的文章共有2篇,一篇(此篇)是介绍 Flutter 中Stateful 组件的生命周期. 第二篇是 Flutter 中与平台相关的生命周期, 博客地址:http://laomen ...

  9. Redis性能篇(二)CPU核和NUMA架构的影响

    Redis被广泛使用的一个很重要的原因是它的高性能.因此我们必要要重视所有可能影响Redis性能的因素.机制以及应对方案.影响Redis性能的五大方面的潜在因素,分别是: Redis内部的阻塞式操作 ...

  10. ORB-SLAM3 细读单目初始化过程(上)

    作者:乔不思 来源:微信公众号|3D视觉工坊(系投稿) 3D视觉精品文章汇总:https://github.com/qxiaofan/awesome-3D-Vision-Papers/ 点击上方&qu ...