NOIp2018集训test-9-15(联考二day1)
T1.矩阵游戏
水题。每一行最后乘的数为x[i],每一列为y[i],暴力算第一行的列的贡献,每一行的列的贡献是公差为所有列的贡献之和的等差数列,然后每一行再乘上行的贡献求和即为答案。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define Formylove return 0
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=,p=1e9+;
typedef long long LL;
typedef double db;
using namespace std;
LL n,m,k,x,y;
LL R[N],S[N],ans,bs,rs;
char o[]; template<typename T>void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} #define ANS
int main() {
#ifdef ANS
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
#endif
read(n); read(m); read(k);
int up=max(n,m);
For(i,,up) R[i]=S[i]=;
For(i,,k) {
scanf("%s",o);
read(x); read(y);
if(o[]=='R') R[x]=R[x]*y%p;
else S[x]=S[x]*y%p;
}
For(i,,m) {
rs=(rs+S[i]*i%p)%p;
bs=(bs+S[i])%p;
}
bs=bs*m%p;
For(i,,n) {
ans=(ans+rs*R[i]%p)%p;
rs=(rs+bs)%p;
}
printf("%lld\n",ans);
Formylove;
}
T2.跳房子
容易想到每次暴力找循环节地跳,复杂度是O(Q*循环节长度),很不幸的是循环节长度似乎是n*m级别的(我想证明循环节长度很小然后失败了)。
考虑分块做法,每一行为一块,预处理出从每一行的第一列开始走m步走到哪一行的第一列,每次先一行一行地跳(很长的也要按行找循环节),再一个一个跳。
如何修改,发现第一行能跳到某一个格子的点是连续的一些列,倒着回去找到一行的列(记录一个l,r)修改这些列即可。
注意修改一个点的权值后是修改可能跳到它的三个点。然后倒着回去的时候l,r因为会从上到下又从下到上蛇皮走位,把下标弄成从0开始然后l,r只管++--判断值的时候取模来处理,不然会debug到死也出不来。。。
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=b;i++)
#define Rep(i,a,b) for(int i=(a);i>=b;i--);
#define Formylove return 0
const int N=;
using namespace std;
typedef long long LL;
typedef double db;
int n,m,q,a[N][N],tx[N],vis[N],ti[N];
int nx,ny;
char o[]; template<typename T>void read(T &x) {
char ch=getchar(); T f=; x=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} void walk(int &x,int &y) {
int t1=a[(x+)%n][(y+)%m];
int t2=a[x][(y+)%m];
int t3=a[(x-+n)%n][(y+)%m];
y=(y+)%m;
if(t1>t2&&t1>t3) x=(x+)%n;
else if(t2>t1&&t2>t3) x=x;
else x=(x-+n)%n;
} int mo(int x,int n) { return (x%n+n)%n; } void change(int x,int y) {
x=mo(x,n); y=mo(y,m);
int ex=x,ey=y;
for(;;) {
walk(ex,ey);
if(!ey) break;
}
int l=x,r=x;
while(y) {
if(a[mo(l,n)][mo(y,m)]>a[mo(l-,n)][mo(y,m)]&&a[mo(l,n)][mo(y,m)]>a[mo(l-,n)][mo(y,m)])
l--;
else if(a[mo(l,n)][mo(y,m)]<a[mo(l-,n)][mo(y,m)]&&(l+>r||a[mo(l+,n)][mo(y,m)]<a[mo(l-,n)][mo(y,m)]))
l++;
if(a[mo(r,n)][mo(y,m)]>a[mo(r+,n)][mo(y,m)]&&a[mo(r,n)][mo(y,m)]>a[mo(r+,n)][mo(y,m)])
r++;
else if(a[mo(r,n)][mo(y,m)]<a[mo(r+,n)][mo(y,m)]&&(r-<l||a[mo(r-,n)][mo(y,m)]<a[mo(r+,n)][mo(y,m)])) r--;
if(l>r) break;
y--;
}
if(l>r) return;
if(r-l+>=n) For(i,,n-) tx[i]=ex;
else {
l=mo(l,n); r=mo(r,n);
if(l<=r) For(i,l,r) tx[i]=ex;
else { For(i,,r) tx[i]=ex; For(i,l,n-) tx[i]=ex; }
}
} #define ANS
int main() {
#ifdef ANS
freopen("jump.in","r",stdin);
freopen("jump.out","w",stdout);
#endif
read(n); read(m);
For(i,,n-) For(j,,m-) read(a[i][j]);
For(i,,n-) {
int x=i,y=;
For(j,,m-) walk(x,y);
tx[i]=x;
}
read(q);
nx=,ny=;
while(q--) {
scanf("%s",o);
if(o[]=='m') {
int k;
read(k);
while(k&&ny!=) {
walk(nx,ny);
k--;
}
int tim=;
vis[nx]=q;
ti[nx]=tim;
while(k>=m) {
k-=m;
tim++;
nx=tx[nx];
if(vis[nx]==q) {
int L=tim-ti[nx];
k=k%(L*m);
break;
}
vis[nx]=q;
ti[nx]=tim;
}
while(k>=m) {
nx=tx[nx];
k-=m;
}
while(k) {
walk(nx,ny);
k--;
}
printf("%d %d\n",nx+,ny+);
}
else {
int x,y,z,l,r;
read(x); read(y); read(z);
x--; y--;
a[x][y]=z;
//For(i,0,n-1) printf("%d ",tx[i]); puts("");
change(x,y-);
change(x-,y-);
change(x+,y-);
//For(i,0,n-1) printf("%d ",tx[i]); puts("");
}
}
Formylove;
}
T3优美序列
这题好神啊,我看了很久很久题解和标程也没看懂,去网上搜了一下,看见了其他学校和我们联考的巨佬的博客
第一个巨佬说:这道题可以秒切
第二个巨佬说:这是最简单的一道题
Orz Orz我被这道题和巨佬们秒了。。。什么分治,还什么归并排序的样子,什么st表,全然懵逼
然后我又继续死啃std,根据代码反推出了一个和分治似乎没有半毛钱关系的做法,不知道是std就是这样想的代码和它写的题解并没有联系还是我反推的方式太诡秘,我来口胡一下
把一个优美的序列排序后差分,每一项是1(废话)
那么考虑这样一个判断序列是否优美的方式,如果序列中存在两个数差为1,序列的权值++,如果序列的权值等于序列长度-1,则序列优美。
那么我用线段树维护序列的权值,从左到右扫整个序列,扫到i时线段树上每个叶子节点j表示j到i的序列的权值,这样每加进一个新的数x,只需要看前面有没有x-1,x+1,把1到那个位置区间+1即可。这样扫到i的时候,j~i的序列优美就转换为j的权值=i-j,把j移到左边,就把每个点j权值事先加上j,那么只需要判断权值是否等于现在的i就好了。
这样询问就可以处理了,把询问按右端点从小到大排序,在线段树上维护的同时,扫到一个右端点就把它加进当前询问的set里,set中按左端点从大到小排序。这样在i处理每个询问的时候,就是问1~l的点的权值中最靠右的一个i的位置,因为不优美的区间权值一定是小于i的,线段树只需要维护最靠右的最大值和它的位置就好了。每次查询的时候就是区间查询。如果l较大的查询到的最大值都小于i,那l较小的询问肯定也没有答案,所以set中按左端点排序,时间复杂度十分ok。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define Formylove return 0
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,a[N],p[N],al[N],ar[N]; template<typename T>void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct node {
int l,id;
node(int l,int id):l(l),id(id){}
friend bool operator <(const node&A,const node&B) {
return A.l>B.l||(A.l==B.l&&A.id<B.id);
}
};
vector<node>vc[N]; #define lc (x<<1)
#define rc ((x<<1)|1)
#define mid ((l+r)>>1)
int mx[N<<],pos[N<<],lz[N<<];
void build(int x,int l,int r) {
mx[x]=pos[x]=r;
if(l==r) return;
build(lc,l,mid); build(rc,mid+,r);
} void down(int x,int l,int r) {
if(!lz[x]) return;
mx[lc]+=lz[x]; lz[lc]+=lz[x];
mx[rc]+=lz[x]; lz[rc]+=lz[x];
lz[x]=; return;
} void update(int x,int l,int r,int ql,int qr,int v) {
if(l>=ql&&r<=qr) {
mx[x]+=v; lz[x]+=v; return;
}
down(x,l,r);
if(ql<=mid) update(lc,l,mid,ql,qr,v);
if(qr>mid) update(rc,mid+,r,ql,qr,v);
mx[x]=max(mx[lc],mx[rc]);
pos[x]=(mx[x]==mx[rc]?pos[rc]:pos[lc]);
} #define pr pair<int,int>
#define fi first
#define se second
pr qry(int x,int l,int r,int ql,int qr) {
if(l>=ql&&r<=qr)
return make_pair(mx[x],pos[x]);
down(x,l,r);
if(qr<=mid) return qry(lc,l,mid,ql,qr);
if(ql>mid) return qry(rc,mid+,r,ql,qr);
pr t1=qry(lc,l,mid,ql,qr),t2=qry(rc,mid+,r,ql,qr);
return t2>=t1?t2:t1;
} int find(int l,int r,int id) {
pr t=qry(,,n,,l);
if(t.fi==r) {
al[id]=t.se; ar[id]=r;
return ;
}
return ;
} set<node>s;
void solve() {
build(,,n);
For(i,,n) {
int up=vc[i].size();
For(j,,up-) s.insert(vc[i][j]);
if(a[i]-&&p[a[i]-]<i) update(,,n,,p[a[i]-],);
if(a[i]+<=n&&p[a[i]+]<i) update(,,n,,p[a[i]+],);
while(!s.empty()) {
node t=*s.begin();
if(!find(t.l,i,t.id)) break;
s.erase(s.begin());
}
}
} #define ANS
int main() {
#ifdef ANS
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
#endif
read(n);
For(i,,n) {
read(a[i]);
p[a[i]]=i;
}
read(m);
For(i,,m) {
int l,r;
read(l); read(r);
vc[r].push_back(node(l,i));
}
solve();
For(i,,m) printf("%d %d\n",al[i],ar[i]);
Formylove;
}
NOIp2018集训test-9-15(联考二day1)的更多相关文章
- NOIp2018集训test-9-22(am/pm) (联考三day1/day2)
szzq学长出的题,先orz一下. day1 倾斜的线 做过差不多的题,写在我自己的博客里,我却忘得一干二净,反而李巨记得清清楚楚我写了的. 题目就是要最小化这个东西 $|\frac{y_i-y_j} ...
- 六省联考2017 Day1
目录 2018.3.18 Test T1 BZOJ.4868.[六省联考2017]期末考试 T2 T3 BZOJ.4870.[六省联考2017]组合数问题(DP 矩阵快速幂) 总结 考试代码 T1 T ...
- NOIp2018集训test-9-16(联考二day2)
T1旋转子段 一开始脑袋抽了花了近一个小时写了个跟这题毫无关系的莫名其妙的代码,一急代码就各种bug,最后t1就花了一个半小时多,然后后面时间不太够了,考得稀烂. 因为每个数存在唯一的中心使得绕这个中 ...
- NOIp2018集训test-10-6/test-10-7 (联考五day1/day2)
昨天考完月考,明天初赛,dcoi2017级今天终于开始停课准备noip了,大概没有比本弱校停课更晚的学校了吧.本来就够菜了,怕是要凉透哦. DAY1 T1石头剪刀布 据说爆搜随便做,但是我觉得我的O( ...
- NOIp2018集训test-10-4/test-10-5 (联考四day1/day2)
这个day1稍微有点毒瘤吧?? DAY1 排列 以前总是把day1t1想太复杂了翻车,差不多往正解的方向想了一下感觉不可能这么复杂这可是noipday1t1啊一定有非常简单的方法然后翻车了?? 题目转 ...
- NOIp2018集训test-10-21 (联考六day1)
今天被高一狂踩,两个手抖,t1一个1写成2,t3一个+=写成=,所谓失之毫厘谬以千里,直接丢了50分. 完全背包 看到背包体积如此之大物品体积如此之小容易很想到贪心,肯定要先加很多很多的性价比最高的最 ...
- NOIp2018集训test-9-7(pm) (联考一day1)
又被辉神吊打了.今天不仅被辉神李巨吊打,还给基本上给全班垫底了. 看到T3就知道是十进制快速幂,全机房考试的当时应该就我会,结果我tm没找到递推. Orz lyc BM直接水过,Orz wys六个fo ...
- SD六校联考二轮
数据差评 D1T1 string 直接模拟 每次 string_u = const_string + string_v 理论得分 30 实际可得 100 D2T1 n^2 理论得分 30 实际可得 1 ...
- P5290 [十二省联考2019]春节十二响
题目地址:P5290 [十二省联考2019]春节十二响 骗分方法 如果你实在一点思路也没有,暴力都不会打,那么请考虑一下骗分. 方法一 输出所有 \(M\) 的和. 期望得分:0分. 实际还有5分 方 ...
随机推荐
- vue eslint修改为4个空格
- web框架express学习一
服务端 node app.jsapp.jslet express = require("express"); let http = require("http" ...
- java中文件下载的思路(参考:孤傲苍狼)
文件下载 文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载 文件下载功能的实现思路: 1.获取要下载的文件的绝对路径 2.获取要下载的文件 ...
- Luogu P2269 [HNOI2002]高质量的数据传输
这题给大家提供一下思路~ (为不想贴代码找借口) 声明:两个思路都是正确的,并且都AC了.(逃) 总体布局 求传输失败率\(1-\prod(1-p_{i})\)最小就是求 传输成功率\(\prod(1 ...
- 上传漏洞科普[1]-文件上传表单是Web安全主要威胁
为了让最终用户将文件上传到您的网站,就像是给危及您的服务器的恶意用户打开了另一扇门.即便如此,在今天的现代互联网的Web应用程序,它是一种 常见的要求,因为它有助于提高您的业务效率.在Facebook ...
- MFC的回调函数
MFC中应该有两类回调函数:一类是源自C的传统回调函数,此类回调函数若非定义为全局函数,而定义在类中的话,要添加static约束,常见的有EnumXXX():一类是消息响应函数,通过成员函数指针实 ...
- HTTP与HTTPS的区别与联系
HTTP与HTTPS的区别与联系 HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure ...
- SSM框架整合思路
SSM框架整合思路 Spring在整合中起到的作用(面试时常问到) Spring管理持久层的mapper. Spring管理业务层的service,service可以调用mapper接口.Spring ...
- [经典]Python 一篇学会多线程
对于python 多线程的理解,我花了很长时间,搜索的大部份文章都不够通俗易懂.所以,这里力图用简单的例子,让你对多线程有个初步的认识. 单线程 在好些年前的MS-DOS时代,操作系统处理问题都是单任 ...
- Codeforces 1183A Nearest Interesting Number
题目链接:http://codeforces.com/problemset/problem/1183/A 题意:求不小于 a 且每位数和能被 4 整除的 最小 n 思路:暴力模拟就好. AC代码: # ...