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分 方 ...
随机推荐
- Java数据库事务四大特性以及隔离级别
四大特性ACID 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚.失败回滚的操作事务,将不能对数据库有任何影响 一致性(Consistency) 一致性是指事 ...
- jQuery与Vue的区别、从jQuery到Vue框架优点总结
一.两者的区别 1.数据与视图分离 2.数据驱动视图 二.从jQuery到Vue框架的总结 1.数据与视图分离,解耦 2.数据驱动视图,只关心数据,DOM操作已经被框架封装
- git上传本地项目带Github上
创建好线上版本库以后就可以在本地进行上传 1.选择好文件夹右击Git Bash Here 2.先创建本地版本库 git init 3.git add README.md 4.git commit -m ...
- PHP ftp_get_option() 函数
定义和用法 The ftp_get_option() 函数返回 FTP 连接的各种运行时选项. 语法 ftp_get_option(ftp_connection,option) 参数 描述 ftp_c ...
- gensim中TaggedDocument 怎么使用
我有两个目录,我想从中读取它们的文本文件并给它们贴上标签,但我不知道如何通过taggedDocument来实现这一点.我以为它可以作为标记文档([strings],[labels])工作,但这显然不起 ...
- 【前端技术】一篇文章搞掂:JS
待补充 //以下等价 if(val) if(val!=null&&val!=undefined&&val!="") //以下等价 if(!val) ...
- STM32嵌入式开发学习笔记(五):中断
我们过去了解了用循环实现延时,或用系统滴答计时器实现延时,但这两种方法都有一种问题:会阻塞处理器的运行.下面我们学习一种不阻塞处理器运行其他事件的功能:时钟中断. 所谓中断,就是让处理器放下手头的事情 ...
- cgo 和 Go 语言是两码事
cgo不是Go 借用 JWZ的一句话 有些人,当他们面临一个问题时,认为“我知道,我会使用 cgo ”.那么现在,他们有了两个问题. 最近有人在 Gopher 的 Slack Channel 上使用 ...
- Linux之nginx-uwagi-django 搭建
1. nginx 1) 使用官方Nginx yum源 [root@nginx ~]# vim /etc/yum.repos.d/nginx.repo [nginx] name=nginx repo b ...
- prototype.原型链.原型链图
//1.几乎所有函数都有prototype属性,这个是个指针,指向原型对象;Function.prototype这个没有 //2.所有对象中都有__proto__属性.(Object.protot ...