NOIP模拟测试13「矩阵游戏·跳房子·优美序列」

矩阵游戏

考试时思路一度和正解一样,考试到最后还是打了80分思路,结果80分打炸了只得了40分暴力分

题解

算出来第一列的总值,每次通过加每两列之间的差值得出下一列的总值

算第一列我们只需要让当前点*行增倍的数量就行了

    for(ll i=1;i<=n;i++){nowlie=(nowlie+elephant(i,1)*hang[i])%mod;sum=(sum+hang[i]);}

算其他列

        nowlie=(nowlie+sum)%mod;

可能这一列会加倍只需乘上就行了

        ans=(ans+nowlie*lie[i])%mod;

思路简单代码好打,然而考试我还是打炸了

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1010101
const ll mod=1e9+7;
ll n,m,nowlie=0,sum=0,ans=0,k;
ll lie[A],hang[A];
char c[5];
ll elephant(ll i,ll j){return ((i-1)*m%mod+j)%mod;
}
int main(){scanf("%lld%lld%lld",&n,&m,&k);for(ll i=1;i<=1000000;i++){hang[i]=1;lie[i]=1;}for(ll i=1,a,x;i<=k;i++){scanf("%s",c+1);scanf("%lld%lld",&a,&x);if(c[1]=='S'){lie[a]=lie[a]*x%mod;}if(c[1]=='R'){hang[a]=hang[a]*x%mod;}}for(ll i=1;i<=n;i++){nowlie=(nowlie+elephant(i,1)*hang[i])%mod;sum=(sum+hang[i]);}for(ll i=1;i<=m;i++){ans=(ans+nowlie*lie[i])%mod;nowlie=(nowlie+sum)%mod;}cout<<ans<<endl;
}

t2,t3卡常题目,AC不了的

跳房子

看了一晚上第三题又看了扫描线,又打了一晚上,又理解了图论tarjan来做第三题,所以我用两个小时把t2A了???????

莫名和考试时思路相似   其实一点也不相似

$85\%$算法

暴力找循环节,剩下数据经过特殊构造你AC不了的,,,,,,,,,

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
char s[10];
#define A 11111111
ll vis[5100][5100],a[5100][5100];
inline int read(){register int ret=0,f=1;register char r;r=getchar();while(!isdigit(r)){if(r=='-') f=-1;r=getchar();}while(isdigit(r)){ret=ret*10+r-'0';r=getchar();}return f*ret;
}
ll p,nowx=1,nowy=1,top=0,n,m;
ll stax[A],stay[A];
void work(ll x){ll tot=0;while(x){ll nx=nowx,ny=nowy,d2=nx+1,d3=nx-1;(nx+1==n+1)?d2=1:d2=nx+1;(nx-1==0)?d3=n:d3=nx-1;if(ny==m) ny=0;ll z1=a[nx][ny+1],z2=a[d2][ny+1],z3=a[d3][ny+1];if(z1>z2&&z1>z3) nowx=nx,nowy=ny+1;else if(z2>z1&&z2>z3) nowx=d2,nowy=ny+1;else if(z3>z1&&z3>z2) nowx=d3,nowy=ny+1;x--;top++;stax[top]=nowx,stay[top]=nowy;if(!vis[nowx][nowy])vis[nowx][nowy]=top;else{tot=top-vis[nowx][nowy];x=x%tot;}}while(top){ll x=stax[top],y=stay[top];vis[x][y]=0;top--;}printf("%lld %lld\n",nowx,nowy);
}
int main(){n=read(),m=read();for(ll i=1;i<=n;i++)for(ll j=1;j<=m;j++)a[i][j]=read();p=read();for(ll i=1,aa,bb,cc;i<=p;i++){scanf("%s",s+1);if(s[1]=='m'){cc=read();work(cc);}if(s[1]=='c'){aa=read(),bb=read(),cc=read();a[aa][bb]=cc;}}
}

$100\%$算法

和找循环节类似但又有很大区别,

思考循环节问题出现在那?

可能会遍历整张图才找到一个循环节,即使你预处理了找到循环节,那么出现change正好改掉循环节,再move找循环节,再change 再move你就被卡死了,复杂度本身就有问题

那么没办法做了吗

建立置换,走到一个点,如果步数大就直接置换,步数小就暴力走

我们用一个线段树来维护这个置换如果从1--m建树,那么t[1]就表示走m步置换成哪里

每次走m步

走的次数就是v/m

根据置换的运算$t^k$就是走了k次每次走t步

通过快速幂算出置换得出结果

那么我们经过%可以快速算出来剩下的,剩下的步数暴力走即可

顺便学了置换的运算

            c.g[i]=a.g[t.g[i]];

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1010101
ll n,m,k,nowx=1,nowy=1;
ll f[2100][2100];
char znsbc[10];
struct node{ll g[2100];node(){for(ll i=1;i<=n;i++)g[i]=i;}node operator *(const node &a){node t=*this,c;for(ll i=1;i<=n;i++)c.g[i]=a.g[t.g[i]];return c;}
}nxt[2100];
struct tree{ll l,r,f;node t;
}tr[10100];
inline void up(ll p){tr[p].t=tr[p<<1].t*tr[p<<1|1].t;return ;
}
inline void built(ll p,ll l,ll r){tr[p].l=l,tr[p].r=r;if(l==r){tr[p].t=nxt[l];return ;}ll mid=(l+r)>>1;built(p<<1,l,mid);built(p<<1|1,mid+1,r);up(p);
}
inline void add(ll p,ll o){
//    printf("l=%lld r=%lld\n",l,r);if(tr[p].l==tr[p].r){tr[p].t=nxt[o];return ;}ll mid=(tr[p].l+tr[p].r)>>1;if(mid>=o)add(p<<1,o);elseadd(p<<1|1,o);up(p);
}
inline node meng(node x,ll k){node ans;for(;k;k>>=1,x=x*x)if(k&1)    ans=ans*x;return ans;
}
inline ll get(ll k,ll flag){if(k==(flag?m+1:n+1))return 1;if(!k)return flag?m:n;return k;
}
inline void change(ll xx,ll yy){ll maxn=0;xx=get(xx,0);yy=get(yy,1);for(ll i=-1;i<=1;i++){ll x=get(xx+i,0),y=get(yy+1,1);if(maxn<f[x][y]) maxn=f[x][y],nxt[yy].g[xx]=x;}return ;
}
inline void move(ll x){while(x)x--,nowx=nxt[nowy].g[nowx],nowy=get(nowy+1,1)/*,printf("x=%lld\n",x)*/;
}
int main(){scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++)for(ll j=1;j<=m;j++)scanf("%lld",&f[i][j]);for(ll i=1;i<=n;i++)for(ll j=1;j<=m;j++)change(i,j);built(1,1,m);scanf("%lld",&k);for(ll i=1,a,b,c,v,o;i<=k;i++){scanf("%s",znsbc+1);if(znsbc[1]=='m'){scanf("%lld",&v);ll len=min(v,m-nowy+1);move(len);v-=len;if(v){nowx=meng(tr[1].t,v/m).g[nowx];v%=m;if(v){move(v);}}printf("%lld %lld\n",nowx,nowy);}else{scanf("%lld%lld%lld",&a,&b,&c);f[a][b]=c;for(ll j=-1;j<=1;j++)change(a+j,b-1)/*,printf("*****\n");*/;o=get(b-1,1);add(1,o);}}
}

 随机数据生成

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll random(ll n)
{return rand()%n;
}
bool a[3210520];
int main()
{freopen("mkd.txt","w",stdout); srand((unsigned)time(0));ll n=random(5)+5,m=random(5)+5;printf("%lld %lld\n",n,m);for(ll i=1;i<=n;i++,puts(""))for(ll j=1;j<=m;j++){ll x=random(550);while(a[x]) x=random(550);printf("%lld ",x);}ll k=random(50)+50;printf("%lld\n",k);for(ll i=1;i<=k;i++){ll op=random(2);if(op) {printf("move ");printf("%lld\n",random(50000)+50000);}else{printf("change ");ll l=random(n)+1;ll r=random(m)+1;printf("%lld %lld %lld\n",l,r,random(50)+50); }}fclose(stdout);
}
View Code

t3做法尤其玄学

傻逼卡常题,傻逼卡常题,傻逼卡常题,毒瘤出题人,毒瘤数据,毒瘤做法

做法1,把序列问题转化为图论????????线段树优化建边+tarjan缩点+线段树维护图中内容我不会

做法2,扫描线,一条性质,若a<=b<=c<=d并且a--c是好区间,b--d是好区间,那么a--d是好区间

假设我们扫描到i i+1,那么如果i i+1在好区间里,那么val[i] val[i+1]都在好区间里,

设好的二元组为相邻两个数,那么区间若为好区间好二元组数量为r-l

用一棵线段树维护二元组数量设为v,若v+l=r则是好区间,假设我们当前扫描到了a[i],那么处于a[i]-1  a[i]+1的位置都要加1

线段树维护一下,细节比较多

做法3,性质若r-l=maxval-minval那么就是一个好区间

那么若maxval到minval之间全部出现那么是一个好区间,那么位置最左最右值出现即可,,

线段树维护一下||st表维护一下

但做法3本身复杂度不对,随机数据下表现优秀,但会被特殊数据卡

分块优化一下

#include<bits/stdc++.h>
#define MAXN 100005
#define min(a,b) ((a<b)?(a):(b))
#define max(a,b) ((a>b)?(a):(b))
using namespace std;
int mn[20][MAXN],mx[20][MAXN],mh[MAXN],a[MAXN],n,mnpos[20][MAXN],mxpos[20][MAXN],ans1[2005][2005],ans2[2005][2005],t;
int bl[MAXN];
vector<int>ld;
void pre()
{for(int i=1;i<=n;i++)for(int j=17;j>=0;j--)if(i>=(1<<j)) {mh[i]=j;break;}for(int i=1;i<=17;++i)for(int j=1;j<=n;++j){mn[i][j]=min(mn[i-1][j],mn[i-1][j+(1<<(i-1))]);mx[i][j]=max(mx[i-1][j],mx[i-1][j+(1<<(i-1))]);mnpos[i][j]=min(mnpos[i-1][j],mnpos[i-1][j+(1<<(i-1))]);mxpos[i][j]=max(mxpos[i-1][j],mxpos[i-1][j+(1<<(i-1))]);}return ;
}
/*const int L=1<<20|1;
char buffer[L],*S,*T;
#define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)*/
inline int Rd()
{int x=0;char c=getchar();while(c>'9'||c<'0')c=getchar();while(c>='0'&&c<='9'){x=x*10+c-48;c=getchar();}return x;
}
inline int gmax(int l,int r)
{return max(mx[mh[r-l+1]][l],mx[mh[r-l+1]][r-(1<<mh[r-l+1])+1]);
}
inline int gmin(int l,int r)
{return min(mn[mh[r-l+1]][l],mn[mh[r-l+1]][r-(1<<mh[r-l+1])+1]);
}
inline int qmax(int l,int r)
{return max(mxpos[mh[r-l+1]][l],mxpos[mh[r-l+1]][r-(1<<mh[r-l+1])+1]);
}
inline int qmin(int l,int r)
{return min(mnpos[mh[r-l+1]][l],mnpos[mh[r-l+1]][r-(1<<mh[r-l+1])+1]);
}
int main()
{
//    freopen("sequence21.in","r",stdin);n=Rd();t=pow(n,0.7);for(int i=1;i<=n;i++) {a[i]=Rd();mn[0][i]=mx[0][i]=a[i];mnpos[0][a[i]]=mxpos[0][a[i]]=i;}int p=0,tot=0;while(p<n){ld.push_back(p+1);for(int i=1;i<=t;i++)bl[p+i]=tot;p+=t;tot++;}pre();memset(ans1,0x3f,sizeof(ans1));memset(ans2,-0x3f,sizeof(ans2));for(int i=0;i<ld.size();i++)for(int j=i;j<ld.size();j++){int l,r;l=ld[i];r=ld[j];int nowmin=gmin(l,r),nowmax=gmax(l,r);int pl=qmin(nowmin,nowmax),pr=qmax(nowmin,nowmax);while(l>pl||r<pr){if(l>pl){nowmin=min(nowmin,gmin(pl,l));nowmax=max(nowmax,gmax(pl,l));l=pl;}if(r<pr){nowmin=min(nowmin,gmin(r,pr));nowmax=max(nowmax,gmax(r,pr));r=pr;}pl=qmin(nowmin,nowmax);pr=qmax(nowmin,nowmax);}ans1[i][j]=l;ans2[i][j]=r;//        cout<<ans1[i][j]<<' '<<ans2[i][j]<<endl;
        }int Q;Q=Rd();while(Q--){register int l,r,ll,rr;l=Rd();r=Rd();ll=bl[l]+1;rr=bl[r]-1;int nowmin=gmin(l,r),nowmax=gmax(l,r);int pl=qmin(nowmin,nowmax),pr=qmax(nowmin,nowmax);while(l>pl||r<pr){ll=bl[l]+1;rr=bl[r]-1;if(l>pl){nowmin=min(nowmin,gmin(pl,l));nowmax=max(nowmax,gmax(pl,l));l=pl;l=min(l,ans1[ll][rr]);}if(r<pr){nowmin=min(nowmin,gmin(r,pr));nowmax=max(nowmax,gmax(r,pr));r=pr;r=max(r,ans2[ll][rr]);}pl=qmin(nowmin,nowmax);pr=qmax(nowmin,nowmax);}printf("%d %d\n",l,r);}return 0;
}

 

转载于:https://www.cnblogs.com/znsbc-13/p/11302998.html

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

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

相关文章

一次测试

$\leq$ $\in[x,y]$ 转载于:https://www.cnblogs.com/znsbc-13/p/11304153.html

java的xml面试题_Java程序员的10个XML面试问答

java的xml面试题XML面试问题在各种编程工作面试中非常受欢迎&#xff0c;包括针对Web开发人员的Java面试 。 XML是一项成熟的技术&#xff0c;通常用作从一个平台传输数据的标准。 XML面试问题包含来自各种XML技术&#xff08;例如XSLT&#xff09;的问题&#xff0c;该技术用于…

【chromium】 Chromium OS的oom机制

前一段时间&#xff0c;运行在Chromium OS上的一个相机应用经常会自己崩溃&#xff0c;进程戛然而止&#xff0c;测试过程中发现使用的内存以肉眼可见的内存增长&#xff0c;当增长到1G左右&#xff0c;应用窗口突然消失&#xff0c;虽然原因不明&#xff0c;但是能猜到个大概&…

了解java.nio.file.Path – 2

在本文的第1部分中&#xff0c;我们研究了java.nio.file.Path类中的大多数API。 在本文中&#xff0c;我们将介绍其余的API。 使用register&#xff08;&#xff09; 该API允许我们注册java.nio.file.WatchService接口的实现&#xff0c;该接口将侦听目录创建&#xff0c;修改…

欧几里德算法求最大公约数

在求两个数的最大公约数方法中&#xff0c; 辗转相除法是比较快的一种方法。 也就是著名的欧几里德方法。 View Code int Gcd(int a, int b){return b0?a:gcd(b, a%b); } View Code #include "iostream"#include "cstdio"#include "cstring"#…

__reduce__

一、__reduce__()介绍 当定义扩展类型时&#xff08;也就是使用Python的C语言API实现的类型&#xff09;&#xff0c;如果你想pickle它们&#xff0c;你必须告诉Python如何pickle它们。 __reduce__ 被定义之后&#xff0c;当对象被Pickle时就会被调用。它要么返回一个代表全局名…

camel.js_Camel 2.11 –具有URL重写功能的HTTP代理路由

camel.js在即将发布的Apache Camel 2.11版本中&#xff0c;我最近添加了对将自定义url重写实现插入基于HTTP的路由&#xff08;http&#xff0c;http4&#xff0c;jetty&#xff09;的支持。 当您使用骆驼代理/桥接HTTP路由时&#xff0c;这使人们可以控制url映射。 例如&…

问题 1044: [编程入门]三个字符串的排序

题目描述输入三个字符串&#xff0c;按由小到大的顺序输出输入3行字符串输出按照从小到大输出成3行样例输入cde afg abc样例输出abc afg cde分析&#xff1a;可以使用java自带方法compareTo()进行两两比较&#xff0c;首先输入三个字符串a,b,c用a和b比较&#xff0c;如果a的值比…

使用JUnit 5进行更清洁的参数化测试

参数化单元测试的总体思路是对不同的数据运行相同的测试方法。 在JUnit 4中创建参数化测试远非完美。 现有体系结构存在许多问题&#xff1a;将参数定义为类字段&#xff0c;并且需要使用构造函数来创建它们&#xff0c;不能将参数化和非参数化测试混合在一个测试类中&#xff…

问题 1045: [编程入门]自定义函数之整数处理

题目描述输入10个整数&#xff0c;将其中最小的数与第一个数对换&#xff0c;把最大的数与最后一个数对换。写三个函数&#xff1b; ①输入10个数&#xff1b;②进行处理&#xff1b;③输出10个数。输入10个整数输出整理后的十个数&#xff0c;每个数后跟一个空格&#xff08;注…

我曾经是怎么做面试官的

阅读提示 更新于2019年2月3日&#xff1a;本文过于注重技巧&#xff0c;很多内容笔者已不再使用。这是成长的必经过程&#xff0c;正如独孤求败的剑术精进之路&#xff0c;先注重技巧&#xff0c;再内化&#xff0c;变得不拘泥于形式。 纵然本文内容已不完全与笔者真正的面试风…

大数据摄取:Flume,Kafka和NiFi

初赛 在构建大数据管道时&#xff0c;我们需要考虑如何吸收出现在通常是Hadoop生态系统大门口的数据量&#xff0c;多样性和速度。 在决定采用哪种工具来满足我们的要求时&#xff0c;诸如可伸缩性&#xff0c;可靠性&#xff0c;适应性&#xff0c;开发时间成本等方面的初步考…

__repr__

class Item: def __init__ (self, name, price): self.name name self.price price # 创建一个Item对象&#xff0c;将之赋给im变量 im Item(鼠标, 29.8) # 打印im所引用的Item对象 print(im) 先看下面程序&#xff1a; 上面程序创建了一个 Item 对象&#xff0c;然后使用 p…

__getattribute__

在类 里面,其实并没有方法这个东西,所有的东西都保存在属性里面,所谓的调用方法其实是类里面的一个同名属性指向了一个函数(方法),返回的是函数的引用,再用 函数() 这种方式就可以调用它 在调用实例的方法的时候,实际上给对象传过去的只是一个字符串而已, 比如 t Test()…

使用精确的Java方法参数

了解如何在Java应用程序中选择正确的方法参数类型并获得更健壮和更短的代码。 我们Java开发人员通常有一个使用方法参数的坏习惯&#xff0c;即不考虑实际需要什么&#xff0c;而只是选择我们习惯的&#xff0c;可用的或首先想到的东西。 考虑以下代表性示例&#xff1a; pri…

Android external storage

File sdCard Environment.getExternalStorageDirectory(); File directory_pictures new File(sdCard, "Pictures"); Log.i(TAG,"directory_pictures"directory_pictures); 存储在external storage 这类文件不应该存在SD卡的根目录下&#xff0c;而应该存…

EnjoyingSoft之Mule ESB开发教程第六篇:Data Transform - 数据转换

目录 1. 数据转换概念2. 数据智能感知 - DataSense3. 简单数据转换组件3.1 Object to JSON3.2 JSON to XML3.3 JSON to Object3.4 XML to JSON4. 企业版的DataWeave Transformer(可视化高级数据转换器)5. 社区版的InfoMapper(自研的可视化数据转换器)本篇主要介绍在Mule ESB中使…

反射和内省_单例设计模式–内省和最佳实践

反射和内省定义&#xff1a; Singleton是“ 四人帮”设计模式的一部分&#xff0c;它属于创新设计模式。 在本文中&#xff0c;我们将更深入地研究Singleton模式的用法。 就建模而言&#xff0c;它是最简单的设计模式之一&#xff0c;但另一方面&#xff0c;就使用的复杂性而言…

福利预告,跳一跳助手即将发布,您不知道还有这些...

福利预告&#xff0c;跳一跳助手即将来临 一周后&#xff0c;即2月9号正式发布 跳一跳助手&#xff0c;免费免费免费提供&#xff01; 透露一下 跳一跳助手的界面是这样滴&#xff1a; 这工具有啥用&#xff1f; 举个栗子&#xff1a; 花城君用该工具&#xff0c;不小心就玩到…

Redis Client Lettuce 5 GA发布

经过13个月的开发阶段和208张已解决的故障单&#xff0c;我很高兴宣布Lettuce 5.0全面上市。 这是一个主要发行版&#xff0c;带有一些重大更改&#xff0c;新的有趣功能以及Java 9兼容性。 从Maven Central获取发布 <dependency><groupId>io.lettuce</groupI…