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. Linux 路由 静态路由

    Linux 路由 静态路由 目录 Linux 路由 静态路由 一.临时生效,使用命令route A.添加到主机的路由 B.添加到网络的路由 C.添加默认路由 D.删除路由 E.查看所有路由信息 二.临 ...

  2. HashSet/HashMap 存取值的过程

    HashSet与HashMap的关系: (1)HashSet底层用的是HashMap来实现的 (2)这个HashMap的key就是放进HashSet中的对象,value就是一个Object类型的对象 ...

  3. 文本单词one-hot编码

    单词->字母->向量 神经网络是建立在数学的基础上进行计算的,因此对数字更敏感,不管是什么样的特征数据都需要以向量的形式喂入神经网络,无论是图片.文本.音频.视频都是一样. one-hot ...

  4. TurtleBot3 Waffle (tx2版华夫)(5)激活你的雷达

    重要提示:请在配网通信成功后进行操作,配网后再次开机需要重新验证通信: 重要提示:[Remote PC]代表PC端.[TurtelBot]代表树莓派端: 5.1.操作步骤 1)[Remote PC]  ...

  5. 第九章节 BJROBOT 多点导航【ROS全开源阿克曼转向智能网联无人驾驶车】

    1.把小车平放在地板上,用资料里的虚拟机,打开一个终端 ssh 过去主控端启动roslaunch znjrobot bringup.launch. 2.再打开一个终端,ssh 过去主控端启动 rosl ...

  6. HIve中 datediff,date_add和date_sub的用法

    1.日期比较函数:datediff语法:datediff(string enddate,string startdate) 返回值:int 说明:返回结束日期减去开始日期的天数. 例如: hive&g ...

  7. Thread线程控制之sleep、join、setDaemon方法的用处

    Thread线程控制之sleep.join.setDaemon方法的用处 1. sleep方法 public static void sleep(long millis) throws Interru ...

  8. flask socketio 踩坑记录

    在使用python3的flask-socketio+socket.io.js的时候报错 在使用python3的flask-socketio+socket.io.js的时候报错"unsuppo ...

  9. java反射-Method中的invoke方法的用法-以及函数式接口和lambda表达式

    作者最近研究框架底层代码过程中感觉自己基础不太牢固,于是写了一点案例,以防日后忘记 接口类:Animals 1 public interface Animals { 2 3 public void e ...

  10. ssh升级以及ssh: symbol lookup error: ssh: undefined symbol: EVP_aes_128_ctr错误处理

    1.解压安装openssl包:(不能卸载openssl,否则会影响系统的ssl加密库文件,除非你可以做两个软连接libcryto和libssl) # tar -zxvf openssl-1.0.1.t ...