2018.09.15模拟总结(T1,T3)
过了一周,终于迎来了第二次模拟(这不是期待的语气),看第一周毒瘤程度,我就觉得接下来的模拟只能更毒瘤。
花了10多分钟读完了三道题,觉得暴力还是挺好写的,然后在每一道题都思索那么几分钟后,觉得还是写暴力靠谱一些……不过还好,一个半点就把暴力都写完了。
然后我就接着想正解……
T1 game
这道题刚开始就觉得是二维线段树,然后瞟了一眼数据范围:1e6 * 1e6,于是就犹豫了。就一直在想能不能行和列各只开一个线段树,最终反正是没想出来,于是开始优化我的暴力。推了半天发现了一个惊天秘密:就是修改的顺序是可以颠倒的:于是我就先O(n)处理了所有行的修改,然后对于所有列的修改,再暴力的O(n2)修改:所以说,只要这个数据行的修改越多,我就越容易拿掉80的点……后来经过【地表最强】lsy的山寨数据测了一下,发现还是稳稳的40分……
暴力以及考场心路历程就说到这吧,该讲讲正解是啥咧。
嗯……概括一下,就是这题没A就是数列没学好。
我们开一个lzy_rol[n], lzy_lin[m]两个标记数组,记录每一行或是每一列要乘上多少。假设我们没有列的操作,那么一列看成一个数,整张图就是一个长度为m的等差数列,不想O(1)的话O(m)就能求出来。现在加上了列的操作。其实就是对于每一个数ai乘上了一个lzy_lin[i],只要按顺序算到ai,然后答案加上ai * lzy_lin[i]就行了…………
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const ll mod = 1e9 + ;
const int maxn = 1e6 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n, m, q;
char c[];
ll lzy_rol[maxn], lzy_lin[maxn];
ll s = , d = , sum = ; ll getnum(int x, int i)
{
return ((ll)(i - ) * m + x) % mod;
} int main()
{
freopen("game.in", "r", stdin);
freopen("game.out", "w", stdout);
n = read(); m = read(); q = read();
for(int i = ; i < maxn; ++i) lzy_rol[i] = lzy_lin[i] = ;
for(int i = ; i <= q; ++i)
{
scanf("%s", c); int x = read(); ll k = read();
if(c[] == 'R') lzy_rol[x] *= k, lzy_rol[x] %= mod;
else lzy_lin[x] *= k, lzy_lin[x] %= mod;
}
for(int i = ; i <= n; ++i)
{
s += getnum(, i) * lzy_rol[i]; s %= mod;
d += lzy_rol[i]; d %= mod;
} //s:首项,d:公差
for(rg int i = ; i <= m; ++i)
{
sum += lzy_lin[i] * s; sum %= mod;
s += d; s %= mod;
}
write(sum); enter;
return ;
}
T2 jump
在考场上我第一反应就是20分暴力,然后chuachuachua15分钟就写完了。于是就直接去搞第三题的暴力了。
第三题暴力写完后又回来看这道题,然后就想到了一个50分的想法:先求出一个跳房子的周期,然后移动每一次k步,只要对周期取模即可。至于修改,那就是暴利修改啦。然而时间不是很够,于是就没写完。
至于正解,我到现在还不是很懂。学姐写的是线段树维护置换。然后正解是一个很奇特的算法,不过这俩都没听懂……据说路由器还有一个更简单的做法,然而没人跟我讲啊……
T3 sequence
我上文已经说过了,当时也是写的暴利。而且还没想到比较正常的O(n2)暴利,自己搞了一个很奇葩的算法:就是先预处理每一个数出现的位置,然后统计当前查询区间没出现的数,然后利用这些数字不断扩大查询区间,直到区间最大值减最小值等于区间长度为止。
正解其实跟我的暴利有点像:要维护两个线段树:第一个是区间最值,第二个是在值域区间中出现位置的最值(所以说,RMQ其实就行了,而且常数更小)。
然后我们要递归的查询:先在询问区间[L, R]中查询最小最大值Min, Max.然后在第二个线段树的区间[Min, Max]中查询出现位置的最值Minl, Minr,再换到第一个线段树在[Minl, Minr]中查询数的最大最小值……直到Max - Min = R - L,这时候的L, R 就是答案。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 1e5 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n, m, a[maxn]; struct Tree
{
int a[maxn];
int l[maxn << ], r[maxn << ], Min[maxn << ], Max[maxn << ];
Tree()
{
Mem(a, );
Mem(l, ); Mem(r, );
Mem(Min, ); Mem(Max, );
}
void build(int L, int R, int now)
{
l[now] = L; r[now] = R;
if(L == R) {Min[now] = Max[now] = a[L]; return;}
int mid = (L + R) >> ;
build(L, mid, now << );
build(mid + , R, now << | );
Min[now] = min(Min[now << ], Min[now << | ]);
Max[now] = max(Max[now << ], Max[now << | ]);
}
int query(int L, int R, int now, bool flg)
{
if(L == l[now] && R == r[now]) return flg ? Max[now] : Min[now];
int mid = (l[now] + r[now]) >> ;
if(R <= mid) return query(L, R, now << , flg);
else if(L > mid) return query(L, R, now << | , flg);
else
{
int ret;
if(flg) ret = max(query(L, mid, now << , flg), query(mid + , R, now << | , flg));
else ret = min(query(L, mid, now << , flg), query(mid + , R, now << | , flg));
return ret;
}
}
}Seq, Num; #define pr pair<int, int>
#define mp make_pair
#define fir first
#define sec second
pr Query(int L, int R)
{
while()
{
int Ml = Seq.query(L, R, , ), Mr = Seq.query(L, R, , );
if(Mr - Ml == R - L) return mp(L, R);
L = Num.query(Ml, Mr, , );
R = Num.query(Ml, Mr, , );
}
} int main()
{
freopen("sequence.in", "r", stdin);
freopen("sequence.out", "w", stdout);
n = read();
for(int i = ; i <= n; ++i) a[i] = read();
for(int i = ; i <= n; ++i) Seq.a[i] = a[i], Num.a[a[i]] = i;
Seq.build(, n, ); Num.build(, n, );
m = read();
for(int i = ; i <= m; ++i)
{
int L = read(), R = read();
pr p = Query(L, R);
write(p.fir); space; write(p.sec); enter;
}
return ;
}
不过这个线段树好像常数很大,然后换了数据后后面几个点就TLE了……那真正的正解就不太懂了。
总的来说今天的考试还是挺顺利的,暴利一个半点很愉快的就写完了。自己估分100左右,结果出成绩后刚好102,顿时觉得自己相当nb。反正想拿的分都拿到了,就没什么遗憾。
2018.09.15模拟总结(T1,T3)的更多相关文章
- Lean Data Innovation Sharing Salon(2018.09.15)
时间:2018.09.15地点:北京国华投资大厦
- 【2018.06.26NOIP模拟】T1纪念碑square 【线段树】*
[2018.06.26NOIP模拟]T1纪念碑square 题目描述 2034年,纪念中学决定修建校庆100周年纪念碑,作为杰出校友的你被找了过来,帮校方确定纪念碑的选址. 纪念中学的土地可以看作是一 ...
- 2018.09.23模拟总结(T2)
T1,T3我就不说啦,反正也不会.主要想讲的是T2. T2用了一个神奇的算法:折半搜索. 因为这个坑爹的数据范围告诉我们暴搜或是状压会TLE,而一半刚好能卡过去. 折半搜索其实跟暴搜没什么区别,就是折 ...
- 2018.09.15点名器(简单dp)
描述 Ssoier在紧张的学习中,杜老师每天给他们传授精妙的知识. 杜老师为了活跃气氛,设计了一个点名器,这个点名器包含一个长度为M的数组(下标1开始),每个元素是一个oier的名字,每次点名的时候, ...
- 2018.09.15 poj1734Sightseeing trip(floyd求最小环)
跟hdu1599差不多.. 只是需要输出方案. 这个可以递归求解. 代码: #include<iostream> #include<cstdio> #include<cs ...
- 2018.09.15 hdu1599find the mincost route(floyd求最小环)
传送门 floyd求最小环的板子题目. 就是枚举两个相邻的点求最小环就行了. 代码: #include<bits/stdc++.h> #define inf 0x3f3f3f3f3f3f ...
- 2018.09.15 bzoj1977:次小生成树 Tree(次小生成树+树剖)
传送门 一道比较综合的好题. 由于是求严格的次小生成树. 我们需要维护一条路径上的最小值和次小值. 其中最小值和次小值不能相同. 由于不喜欢倍增我选择了用树链剖分维护. 代码: #include< ...
- 2018.09.15 秘密的牛奶管道SECRET(次小生成树)
描述 约翰叔叔希望能够廉价连接他的供水系统,但是他不希望他的竞争对手知道他选择的路线.一般这样的问题需要选择最便宜的方式,所以他决定避免这种情况而采用第二便宜的方式. 现在有W(3 <= W & ...
- 2018.09.15 vijos1053Easy sssp(最短路)
传送门 貌似可以最短路时同时判定负环啊. 但我不想这样做. 于是写了一个dfs版的判环,bfs版的求最短路. 代码: #include<iostream> #include<ccty ...
随机推荐
- 使用k8s创建容器一直处于ContainerCreating状态
容器报错信息为(两种): FailedSynError syncing pod, skipping: failed to {kubelet 127.0.0.1} Warning FailedSync ...
- [javaSE] GUI(jar包双击运行)
首先应该在java文件中定义包名,package 包名 带包编译成class文件 切换到目录下,使用jar -cvf xx.jar 包名,就是把那个包放到xx.jar包里面 此时双击会报错,找不到要执 ...
- springboot的依赖注入报null的问题
最近使用springboot开发项目,使用到了依赖注入,频繁的碰到注入的对象报空指针,错误如下 java.lang.NullPointerException: null at com.mayihc.a ...
- 面向对象,继承,浏览器,上传文件, ajax
'use strict'; //父类 class Student2{ constructor(name){ this.name = name || 'tom'; } hello(){ console. ...
- Tabindex
1.tabindex 属性可以设置键盘中的TAB键在控件中的移动顺序,及焦点的顺序 2. tabindex 属性值范围在1到32767之间 3. 默认的 tabindex 的值为 0 ,将排在所有指定 ...
- RHEL5.X 重启网卡出现./network-functions: line 78: .: ifcfg-eth0: file not found
错误信息: 红帽RHEL5.5系统,重启网卡报错 [root@localhost network-scripts]# service network restart Shutting down int ...
- sql With(NoLock),With(ReadPast)
--------------- create table tmp1 ( id int primary key, name ) ) ----------- insert into tmp1(id,nam ...
- Oracle 通过出生日期计算年龄
方法一: SELECT TRUNC(months_between(sysdate, birth)/12) AS age from mytable 方法二: select TRUNC((to_char( ...
- bat 常见问题及小实例
bat 常用命令小实例 常见问题: 1.如果你自己编写的.bat文件,双击打开,出现闪退 原因:执行速度很快,执行完之后,自行关闭 解决办法:在最后面一行加上 pause 例如: @echo off ...
- Linux修改Oracle用戶
Linux下SSH登陆后: su - Oracle; sqlplus /nolog; conn system/密码; 或者 connect/as sysdba; alter user 用户名 iden ...