【周末狂欢赛6】[AT1219]历史研究(回滚莫队),大魔法师(矩阵+线段树),单峰排列

文章目录

  • T1:单峰排列
    • 题目
    • 题解
    • code
  • T2:历史研究
    • 题目
    • 题解
    • code
  • T3:大魔法师
    • 题目
    • 题解
    • code

我可能这辈子都更不出来狂欢赛5了,先咕咕

T1:单峰排列

题目

一个n的全排列A[i]是单峰的,当且仅当存在某个x使得A[1]<A[2]<…<A[x]>A[x+1]>…> A[n]
例如,对于9的全排列,125798643是一个单峰排列,123456789也是一个单峰排列,但356298741就不是
试求n的单峰全排列的个数

输入格式
输入一个数n
输出格式
输出n的全排列中单峰排列的个数。
由于这个数可能很大,因此你只需要输出它mod 1234567的值。

样例
输入样例:
3
输出样例:
4
样例说明 共有以下4种方案: 123 132 231 321
数据范围与提示
n<=2 000 000 000

题解

暴力打表找到规律2n−12^{n-1}2n1
在这里插入图片描述
简单证明一下:
我们把最大值即最高峰固定后,剩下的n−1n-1n1个数会有两种选法,在最大值左边或右边2n−12^{n-1}2n1
理论上还要乘以一个阶乘,但是我们发现要成为单峰的话,同在最大值左边的数相对位置是固定的,是不能进行乱排的,证毕!!
在这里插入图片描述

code

#include <cstdio>
#define mod 1234567
#define LL long long
int n;
LL qkpow ( LL x, LL y ) {LL ans = 1;while ( y ) {if ( y & 1 )ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}
int main() {scanf ( "%d", &n );LL ans = qkpow ( 2, n - 1 );printf ( "%lld", ans % mod );return 0;
}

T2:历史研究

题目

IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记。JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件。

日记中记录了连续N天发生的时间,大约每天发生一件
事件有种类之分,第i天(1<=i<=N)发生的事件的种类用一个整数XiX_iXi表示,XiX_iXi 越大,事件的规模就越大。

JOIJOI教授决定用如下的方法分析这些日记:
选择日记中连续的一些天作为分析的时间段
事件种类t的重要度为t*(这段时间内重要度为t的事件数)
计算出所有事件种类的重要度,输出其中的最大值 现在你被要求制作一个帮助教授分析的程序,每次给出分析的区间,你需要输出重要度的最大值。

输入输出格式
输入格式
第一行两个空格分隔的整数N和Q,表示日记一共记录了N天,询问有Q次
接下来一行N个空格分隔的整数X1...XNX_1...X_NX1...XN表示第i天发生的事件的种类
接下来Q行,第i行(1<=i<=Q)有两个空格分隔整数AiA_iAiBiB_iBi表示第i次询问的区间为[Ai,Bi][A_i,B_i][Ai,Bi]

输出格式
输出Q行,第i行(1<=i<=Q)一个整数,表示第i次询问的最大重要度

输入输出样例
输入:
5 5
9 8 7 8 9
1 2
3 4
4 4
1 4
2 4
输出:
9
8
8
16
16
数据范围
1<=N<=105,1<=Q<=105,1<=Xi<=109(1<=i<=N)1<=N<=10^5,1<=Q<=10^5, 1<=X_i<=10^9 (1<=i<=N)1<=N<=105,1<=Q<=105,1<=Xi<=109(1<=i<=N)

题解

这道题首先肯定能反应是莫队,但是答案告诉你TTT了,所以我们要学习一个新的回滚莫队
在这里插入图片描述
假设要查询[l,r][l,r][l,r]区间,按照平时我们要移动curl,currcurl,currcurl,curr,但是我们转变想法对于lll同在一个分块的查询,每一次都把curlcurlcurl回拨到这一区域的最后处然后移动到lll
在这里插入图片描述
但是这张图是错的,你看出来了吗?因为同在一个块的操作rrr一定是递增的,所以上图中的第二根红线应该在最后一个竖黑线的右边

具体操作细节在code中有体现

code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream> 
#include <algorithm>
using namespace std;
#define LL long long
#define maxn 100005
struct node {int l, r, id;
}query[maxn];
int n, q, T;
int block[maxn];
LL result;
LL a[maxn], val[maxn], cnt[maxn], tot[maxn], ans[maxn]; bool cmp ( node x, node y ) {//以块为第一关键字,右端点为第二关键字 return block[x.l] == block[y.l] ? x.r < y.r : block[x.l] < block[y.l];
}void add ( int x ) {cnt[a[x]] ++;result = max ( result, cnt[a[x]] * val[a[x]] );//当规模为i的时间多了一件,重要度就多了i 
}
void remove ( int x ) {cnt[a[x]] --;
}int main() {scanf ( "%d %d", &n, &q );T = sqrt ( n );for ( int i = 1;i <= n;i ++ ) {scanf ( "%lld", &a[i] );block[i] = ( i - 1 ) / T + 1;val[i] = a[i];}int num = block[n];//离散化,1e9最多只会变成1e5,但是规模在计算时要用原来的,所以不能直接替代 sort ( val + 1, val + n + 1 );int len = unique ( val + 1, val + n + 1 ) - val - 1;for ( int i = 1;i <= n;i ++ )a[i] = lower_bound ( val + 1, val + len + 1, a[i] ) - val;	for ( int i = 1;i <= q;i ++ ) {scanf ( "%d %d", &query[i].l, &query[i].r );query[i].id = i;}sort ( query + 1, query + q + 1, cmp );int i = 1;//已经处理到哪一个query操作了 for ( int id = 1;id <= num;id ++ ) {//依次处理每一块int tail = min ( n, id * T );//有可能块数乘以大小反而炸了n int curl = tail + 1, curr = tail;result = 0;memset ( cnt, 0, sizeof ( cnt ) );//每一个块都重新开始,与其他块无瓜for ( ;block[query[i].l] == id;i ++ ) {//属于同一块的每个操作一定是右端点递增的 int l = query[i].l, r = query[i].r;if ( block[query[i].l] == block[query[i].r] ) {//整一个询问都在该块中,暴力求解 LL sum = 0;//不能用result,该次询问根本没用到块以外的元素 for ( int k = l;k <= r;k ++ )tot[a[k]] = 0;//注意不是对tot[k]清零 for ( int k = l;k <= r;k ++ ) {tot[a[k]] ++;sum = max ( sum, tot[a[k]] * val[a[k]] );}ans[query[i].id] = sum;continue;}while ( curr < r )add ( ++ curr );//curr贡献已经算过,所以先加后算,curl同理 LL tmp = result;//r一定是递增的,记录下此时块的末尾到n的ans,方便下面的还原 while ( curl > l )add ( -- curl );ans[query[i].id] = result;while ( curl <= tail )//把curl拨回到下一个块的开头,表示没有一个元素,等到下一次移动到新的l remove ( curl ++ );result = tmp;//重置起始值}}for ( int i = 1;i <= q;i ++ )printf ( "%lld\n", ans[i] );return 0;
} 

T3:大魔法师

题目

中二病患者 大魔法师小 L 制作了nnn个魔力水晶球,每个水晶球有水、火、土三个属性的能量值。小 L 把这 个水晶球在地上从前向后排成一行,然后开始今天的魔法表演。

我们用Ai,Bi,CiA_i,B_i,C_iAi,Bi,Ci分别表示从前向后第iii个水晶球(下标从 开始)的水、火、土的能量值。

小 L 计划施展mmm次魔法。每次,他会选择一个区间[l,r][l,r][l,r],然后施展以下3大类、7种魔法之一:

魔力激发:令区间里每个水晶球中特定属性的能量爆发,从而使另一个特定属性的能量增强。具体来说,有以下三种可能的表现形式:
火元素激发水元素能量:令Ai=Ai+BiA_i=A_i+B_iAi=Ai+Bi
土元素激发火元素能量:令Bi=Bi+CiB_i=B_i+C_iBi=Bi+Ci
水元素激发土元素能量:令Ci=Ci+AiC_i=C_i+A_iCi=Ci+Ai
需要注意的是,增强一种属性的能量并不会改变另一种属性的能量,例如Ai=Ai+BiA_i=A_i+B_iAi=Ai+Bi并不会使BiB_iBi增加或减少。

魔力增强:小 L 挥舞法杖,消耗自身vvv点法力值,来改变区间里每个水晶球的特定属性的能量。具体来说,有以下三种可能的表现形式:

火元素能量定值增强:令Ai=Ai+vA_i=A_i+vAi=Ai+v
水元素能量翻倍增强:令Bi=Bi∗vB_i=B_i*vBi=Biv
土元素能量吸收融合:令Ci=vC_i=vCi=v
魔力释放:小L将区间里所有水晶球的能量聚集在一起,融合成一个新的水晶球,然后送给场外观众。生成的水晶球每种属性的能量值等于区间内所有水晶球对应能量值的代数和。需要注意的是,魔力释放的过程不会真正改变区间内水晶球的能量。

值得一提的是,小 L 制造和融合的水晶球的原材料都是定制版的 OI 工厂水晶,所以这些水晶球有一个能量阈值998244353998244353998244353 。当水晶球中某种属性的能量值大于等于这个阈值时,能量值会自动对阈值取模,从而避免水晶球爆炸。

小 W 为小 L(唯一的)观众,围观了整个表演,并且收到了小 L 在表演中融合的每个水晶球。小 W 想知道,这些水晶球蕴涵的三种属性的能量值分别是多少
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题解

首先大家都能想到线段树,我当时直接暴力线段树开搞,后来操作时写崩了,这个更改太给力
况且因为有懒标记的介入,a,b,ca,b,ca,b,c都会改了后再彼此影响,我们根本不知道先后顺序
那咱不用懒标记呗
在这里插入图片描述
那么怎么能将懒标记按顺序叠加呢?矩阵!!!
在这里插入图片描述
对于操作1,即乘上
(100110001)\begin{pmatrix} 1&0&0\\ 1&1&0\\ 0&0&1\\ \end{pmatrix} 110010001
操作2,乘上
(100010011)\begin{pmatrix} 1&0&0\\ 0&1&0\\ 0&1&1\\ \end{pmatrix} 100011001
操作3,乘上
(101010001)\begin{pmatrix} 1&0&1\\ 0&1&0\\ 0&0&1\\ \end{pmatrix} 100010101
操作4,我们发现怎么加常数?多给矩阵开一位(上面就不再次多余重复),乘上
(100001000010v001)\begin{pmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&1&0\\ v&0&0&1\\ \end{pmatrix} 100v010000100001
操作5,乘上
(10000v0000100001)\begin{pmatrix} 1&0&0&0\\ 0&v&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{pmatrix} 10000v0000100001
操作6,乘上
(10000100000000v1)\begin{pmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&0&0\\ 0&0&v&1\\ \end{pmatrix} 10000100000v0001


然后矩阵的懒标记就可以直接叠加了,最后送大家五句忠告
在这里插入图片描述

1、此做法常数大,写的不好看会100–>45
2、矩阵从0开始,别从1,某朋友MLE
3、矩阵逼着4开,多开1,亲测TLE
4、longlong比int取模会慢一倍,所以你懂的
5、取模本身也很慢,能不取模就不取模

code

#include <cstdio>
#include <cstring>
#define maxn 250005
const int mod = 998244353;
struct Matrix {int c[4][4];
//开成c[5][5]就T了一个点,因为我们每次都用了memset,多清了一行,浪费时间 Matrix () {memset ( c, 0, sizeof ( c ) );}
}unit, ret, A[maxn], tag[maxn << 2], tree[maxn << 2];
//unit是单位矩阵 void read ( int &x ) {x = 0;char s = getchar();while ( s < '0' || s > '9' )s = getchar();while ( '0' <= s && s <= '9' ) {x = ( x << 1 ) + ( x << 3 ) + ( s - '0' );s = getchar();}
}int add ( int x, int y ) {x = 1ll * x + y;return x >= mod ? x - mod : x;
}Matrix operator + ( Matrix x, Matrix y ) {Matrix ans;for ( int i = 0;i < 4;i ++ )ans.c[0][i] = add ( x.c[0][i], y.c[0][i] );return ans;
}void build ( int t, int l, int r ) {tag[t] = unit;if ( l == r ) {tree[t] = A[l];return;}int mid = ( l + r ) >> 1;build ( t << 1, l, mid );build ( t << 1 | 1, mid + 1, r );tree[t] = tree[t << 1] + tree[t << 1 | 1];
}void MakeMark ( int t, Matrix f ) {Matrix ans;for ( int i = 0;i < 4;i ++ )for ( int j = 0;j < 4;j ++ )if ( f.c[i][j] )ans.c[0][j] = add ( ans.c[0][j], 1ll * tree[t].c[0][i] * f.c[i][j] % mod );tree[t] = ans;ans = Matrix();for ( int i = 0;i < 4;i ++ )for ( int j = 0;j < 4;j ++ )if ( tag[t].c[i][j] ) //稀疏矩阵优化 for ( int k = 0;k < 4;k ++ )if ( f.c[j][k] )ans.c[i][k] = add ( ans.c[i][k], 1ll * tag[t].c[i][j] * f.c[j][k] % mod );tag[t] = ans;
}void pushdown ( int t ) {MakeMark ( t << 1, tag[t] );MakeMark ( t << 1 | 1, tag[t] );tag[t] = unit;//注意清除标记就是变成单位矩阵不是0 
}void modify ( int t, int l, int r, int L, int R, Matrix f ) {if ( L <= l && r <= R ) {MakeMark ( t, f );return;}int mid = ( l + r ) >> 1;pushdown ( t );if ( L <= mid )modify ( t << 1, l, mid, L, R, f );if ( mid < R )modify ( t << 1 | 1, mid + 1, r, L, R, f );tree[t] = tree[t << 1] + tree[t << 1 | 1];
}Matrix query ( int t, int l, int r, int L, int R ) {if ( L <= l && r <= R )return tree[t];pushdown ( t );int mid = ( l + r ) >> 1;if ( R <= mid )return query ( t << 1, l, mid, L, R );else if ( mid < L )return query ( t << 1 | 1, mid + 1, r, L, R );elsereturn query ( t << 1, l, mid, L, R ) + query ( t << 1 | 1, mid + 1, r, L, R );
}int main() {int n, m;read ( n );for ( int i = 1;i <= n;i ++ ) {for ( int j = 0;j < 3;j ++ )read ( A[i].c[0][j] );A[i].c[0][3] = 1;}for( int i = 0;i < 4;i ++ )unit.c[i][i] = 1;build ( 1, 1, n );read ( m );int opt, l, r, v;for ( int i = 1;i <= m;i ++ ) {read ( opt );read ( l );read ( r );if ( 4 <= opt && opt <= 6 )read ( v );if ( opt == 7 ) {Matrix ans = query ( 1, 1, n, l, r );printf ( "%d %d %d\n", ans.c[0][0], ans.c[0][1], ans.c[0][2] );continue;}ret = unit;//重置成单位矩阵再进行修改操作 switch ( opt ) {case 1 : ret.c[1][0] = 1;break;case 2 : ret.c[2][1] = 1;break;case 3 : ret.c[0][2] = 1;break;case 4 : ret.c[3][0] = v;break;case 5 : ret.c[1][1] = v;break;case 6 : ret.c[2][2] = 0, ret.c[3][2] = v;break;}modify ( 1, 1, n, l, r, ret );}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YBTOJ:圈套问题(分治法、鸽笼原理)

文章目录题目描述数据范围解析代码图片转载自&#xff1a; https://blog.csdn.net/weixin_43346722/article/details/118435430题目描述 平面上有 n个点&#xff0c;用n个大小相同的圆分别将一个点作为圆心&#xff0c;同时满足圆圈不相交&#xff0c;求圆的最大半径。 数据范…

CF1598E-Staircases【计数】

正题 题目链接:https://www.luogu.com.cn/problem/CF1598E 题目大意 给出一个nmn\times mnm的网格图&#xff0c;开始所有都是黑色的&#xff0c;qqq次取反一个格子的颜色&#xff0c;然后求楼梯的数量。 楼梯定义为全黑色的下/右交替的格子集。 1≤n,m≤1000,1≤q≤1041\le…

ASP.NET Core 实战:使用 NLog 将日志信息记录到 MongoDB

一、前言在项目开发中&#xff0c;日志系统是系统的一个重要组成模块&#xff0c;通过在程序中记录运行日志、错误日志&#xff0c;可以让我们对于系统的运行情况做到很好的掌控。同时&#xff0c;收集日志不仅仅可以用于诊断排查错误&#xff0c;由于日志同样也是大量的数据&a…

532. 货币系统

532. 货币系统 题意&#xff1a; 有 n 种不同面额的货币&#xff0c;第 i 种货币的面额为 a[i]&#xff0c;每一种货币都有无穷多张&#xff0c;货币之间可以彼此代替&#xff0c;比如6等于两张3&#xff0c;问有多少种货币是不可替代的 题解&#xff1a; 我们换一个问…

概率期望题(期望 DP)做题记录

概率期望题(期望 DP)做题记录 P3830 [SHOI2012]随机树 难点在于第二问&#xff1a;生成树的期望深度。 不 wei zhuo 捏&#xff0c;设 \(dp_{i,j}\) 表示已经有了 \(i\) 个叶子结点&#xff0c;深度大于 \(j\) 的概率。 考虑枚举一棵子树的大小&#xff0c;转移方程如下&#x…

[学习笔记] 伸展树splay详解+全套模板+例题[Luogu P3369 【模板】普通平衡树]

文章目录引入概念全套模板变量声明updaterotate旋转splay操作insert插入delete删除查找x的位置查找第k大前驱/后继极小值-inf和极大值inf的作用例题&#xff1a;P3369 【模板】普通平衡树题目code声明一下&#xff0c;许多代码的注解都在模板代码里面写了的&#xff0c;所以正文…

2021.9.23模拟

前言 174pts 40502460 四个暴力分 qwq T1想切结果矩乘T飞了。。。 不要迷信矩乘&#xff0c;这玩意也是会T的… 考场 先看题 感觉T1和T最可做 T3期望想到zld的全排列大法了&#xff0c;但是似乎只能线性… T4是初始化加强版&#xff0c;思路倒是有&#xff0c;但是不想写&am…

AT1981-[AGC001C]Shorten Diameter

正题 题目链接:https://www.luogu.com.cn/problem/AT1981 题目大意 给出nnn个点的一棵树&#xff0c;每次你可以删除一个叶子&#xff0c;求最少的操作数使得树的直径长度不超过kkk。 1≤n,k≤20001\leq n,k\leq 20001≤n,k≤2000 解题思路 开始以为是dpdpdp啥的&#xff0c…

手写AspNetCore 认证授权代码

在普通的MVC项目中 我们普遍的使用Cookie来作为认证授权方式&#xff0c;使用简单。登录成功后将用户信息写入Cookie&#xff1b;但当我们做WebApi的时候显然Cookie这种方式就有点不适用了。在dotnet core 中 WebApi中目前比较流行的认证授权方式是Jwt (Json Web Token) 技术。…

FWT 学习笔记

FWT 学习笔记 学的时候比较匆忙&#xff0c;于是就学一个 \(\texttt{or,and,xor}\) 卷积跑路。 P4717 【模板】快速莫比乌斯/沃尔什变换 (FMT/FWT) 前置知识&#xff1a;高维前缀和&#xff0c;下面前缀和的操作大多都是用高维前缀和来实现的。 设有两个长度为 \(2^n\) 的序列 …

大盗阿福

大盗阿福 题意&#xff1a; 长度为n的数组a&#xff0c;不能取连续的数&#xff0c;问所能取的最大值是多少 题解&#xff1a; 设dp[i][0]表示第i个数不选&#xff0c;dp[i][1]表示第i个数选 如果第i个数不选&#xff0c;那么第i-1个数可以选也可以不选&#xff0c;我们取最…

YBTOJ:采矿战略(线段树维护dp、树链剖分)

文章目录题目描述解析代码题目描述 所谓线段树维护dp&#xff0c;就是在线段树上维护dp &#xff08;逃&#xff09; 解析 把树剖一下后就变成了区间问题 考虑建一棵线段树&#xff0c;每一个结点都是一个背包 这样就能区间查询&#xff0c;也能带修了 这种做法复杂度其实并不…

【用皇宫三十六计生存法则带你走进LCT(动态树)】LCT概念+模板+例题【洛谷P3690 Link Cut Tree(动态树)】

文章目录LCT概念模板rotatoisrootsplayaccessmakerootsplitfindrootlinkcut封装版例题题目code普通版code封装版这篇博客主要是帮助大家理解各个模板及LCTLCTLCT的意思&#xff0c;方便理解&#xff0c;模板写法的理解在代码里有注释详解&#xff0c;如果要看原理的话&#xff…

AGC002(D~F)【Kruskal重构树,博弈论,dp】

正题 AT1998 [AGC002D] Stamp Rally【Kruskal重构树,倍增】 https://www.luogu.com.cn/problem/AT1998 题目大意 给出nnn个点mmm条边的一张无向图&#xff0c;qqq次询问两个人分别从x,yx,yx,y&#xff0c;要求总共经过zzz个点的情况下经过边的最大编号的最小值。 1≤n,m,q≤…

迈向现代化的 .Net 配置指北

1. 欢呼 .NET Standard 时代我现在已不大提 .Net Core&#xff0c;对于我来说&#xff0c;未来的开发将是基于 .NET Standard&#xff0c;不仅仅是 面向未来 &#xff0c;也是 面向过去&#xff1b;不只是 .Net Core 可以享受便利&#xff0c; .NET Framework 不升级一样能享受…

DP 套 DP

DP 套 DP 学习笔记 大致内容 DP 套 DP 就是将一个简单 DP 的状态压缩起来放到新的 DP 中当做状态进行 DP 的过程。 常用于计算简单 DP 的答案为 \(k\) 的转移方案的数量。 一般都需要 decode 和 recode 操作&#xff0c;这里和 插头DP/轮廓线DP 有异曲同工之妙&#xff01; 例题…

acwing提高组 第一章 动态规划

文章目录数字三角形模型最长上升子序列模型背包模型状态机模型状态压缩DP区间DP树形DP数位DP单调队列优化DP斜率优化DPoj链接数字三角形模型 AcWing 1015. 摘花生1357人打卡 AcWing 1018. 最低通行费1279人打卡 AcWing 1027. 方格取数1158人打卡 AcWing 275. 传纸条933人打卡 …

YBTOJ洛谷P2042:维护数列(平衡树)

文章目录题目描述解析删除区间插入数列修改&翻转区间和&最大子段和代码传送门题目描述 解析 阴间题… 这不是裸的板子吗&#xff1f; 国赛真的有人能把这题写出来吗… 应该算一道练习作用很强的题了 写完这题&#xff0c;各种平衡树维护区间操作的方法可以说是毕业了吧…

CAP 2.4版本发布,支持版本隔离特性

前言自从上次 CAP 2.3 版本发布 以来&#xff0c;已经过去了几个月的时间&#xff0c;这几个月比较忙&#xff0c;所以也没有怎么写博客&#xff0c;趁着2019年到来之际&#xff08;现在应该是2019年开始的时候&#xff09;&#xff0c;CAP也发布了2018年的最后一个大版本 2.4&…

AT2005-[AGC003E]Sequential operations on Sequence【差分,思维】

正题 题目链接:https://www.luogu.com.cn/problem/AT2005 题目大意 开始有一个1∼n1\sim n1∼n依次排列的序列&#xff0c;然后QQQ次&#xff0c;第iii次把序列长度变为aia_iai​&#xff0c;不足的从前往后循环填充。 求最后每个数字的出现次数。 1≤n,q≤105,1≤ai≤10181…