[考试反思]1101csp-s模拟测试97:人品

 

上来粘6个图皮一下。(之后粘排行榜是否是都应该粘两份啊。。。文件出入的确挺难受的)数组

话说最近RP为何会这么高啊???我干什么好事了???不知道。ide

此次考试的题挺有水准的,可是个人分数挺没水准的。函数

T1打表找规律。严格来讲不是打表找规律,是看样例找规律而后手模一个表“验证”了规律。优化

先作的T2简单dp这个没的说,数据范围出到$10^{100}$复杂度也能接受(可是要写高精了),出题人可能把T2弄成送分题了。spa

但是都不用矩阵快速幂,因此就这么水过了。excel

T3的话出题人想复杂了。(?)code

拿二维线段树能作复杂度也没毛病,那么为何要分那么多类讨论呢?blog

因此说我仍是没什么水准。骗分能力却是不错。(虽然说这个骗分好像挺有脸的。。)递归

并且T3好像过不去对拍,在n超过1000的时候大概每2400组数据错一个(在值域很小的时候),多是暴力挂了?游戏

固然对拍让我发现了一处错误从WA5里拯救了我。

也不知道这样的RP能维持到何时吧。。。

记得数组开大!!!不爆内存上限还不会算的时候为何不开大一点呢?

丢了个AK。但不是很难过。这要是平时可能又要跳起来了吧2333

 

T1:小盆友的游戏

要听一下找规律的过程吗?证实的话仍是找$LNC$或者是看题解吧。

题解里都说了这是打表找规律题那么为何不打表呢?

首先看样例,6个?出题人这么好?

其实就提醒了我这须要找规律。

而后根据部分分和前4个样例直接拿下50分。

而后看第5个,相较于第二个,它多了一个跟班,答案少了1。

而后看第6个,相较于第三个,它多了两个跟班,答案少了3。

根据1->1和2->3,那么猜想一下数列,要么是1/3/5/7要么是1/3/7/15。

直觉让咱们选择后者,由于后者就是前50分部分分的式子!(有小变化,指数少了1)

可是这样很不严谨。因此首先咱们把前4个样例代入后来发现的式子,发现知足规律。

而后把n=4的4种状况所有都画出来手解方程,发现4种状态都知足。

(若是你还不放心,能够像cbx同样把n=5的6中状况也来一遍,可是花费的时间可能比较长)

其实我也不是这么不正经,我尝试dp来着,可是没作出来,发现没有搜索的部分分,因而就认为这是一个结论题。

指望得分:50分。

 1 #include<cstdio>
 2 #define mod 1000000007
 3 int cnt[100005],n,ans,pw[100005];
 4 int main(){
 5     freopen("game.in","r",stdin);
 6     freopen("game.out","w",stdout);
 7     scanf("%d",&n);
 8     for(int i=1,x;i<=n;++i)scanf("%d",&x),cnt[x>0?x:0]++;
 9     for(int i=1;i<=n;++i)pw[i]=((pw[i-1]<<1)+1)%mod;
10     ans=pw[n-1];
11     for(int i=1;i<=n;++i)ans=(ans-pw[cnt[i]]+mod)%mod;
12     printf("%d\n",ans);
13 }
View Code

 

T2:花

没有矩阵快速幂的矩阵快速幂优化dp题。

状态只有:1连击,2连击,3连击,以前3连击过而如今只有1连击,以前3连击过而如今有2连击。以及已经非法的状态。

 1 #include<cstdio>
 2 #define mod 1000000007
 3 long long dp[6][100005],S,N;
 4 int main(){
 5     freopen("flower.in","r",stdin);
 6     freopen("flower.out","w",stdout);
 7     int t;scanf("%d",&t);
 8     while(t--){
 9         scanf("%lld%lld",&N,&S);S--;
10         dp[1][1]=S+1;
11         for(int i=2;i<=N;++i)
12             dp[1][i]=(dp[1][i-1]+dp[2][i-1])*S%mod,
13             dp[2][i]=dp[1][i-1],
14             dp[3][i]=dp[2][i-1],
15             dp[4][i]=(dp[3][i-1]+dp[4][i-1]+dp[5][i-1])*S%mod,
16             dp[5][i]=dp[4][i-1];
17         printf("%lld\n",(dp[3][N]+dp[4][N]+dp[5][N])%mod);
18     }
19 }
View Code

 

T3:表格

强烈呼吁这道题提交以前检查文件!一卡3分钟!!!

update太多了因而直接说在前面:个人时空复杂度都是常数较小的$O(n^2)$。(暴力碾标算2333怪不得开了8s)

因此我是考场上水过的。正在看正解。

时空复杂度都是$O(nlog^2n)$的与正解一致。可是空间复杂度常数很大,时间复杂度的常数较小。

update:空间复杂度是错误的!空间复杂度为$O(16n^2)$,因此下文的剪枝颇有必要(由于是动态开点因此剪枝能够节约内存)

再update:空间复杂度没那么烂。由于每次查询至多经历$O(log^23n)$个节点因此n次操做的话总的空间最大也就$O(nlog^2n)$

可是其实$O(nlog^23n)$也不知足要求,因此仍是须要剪枝。

其实能够在update函数执行时进行空间回收,可是不必。。。

再再update:QAQ时间复杂度又被hack了。$O(n)$的。。。会被长条卡掉。。。因此总的时空复杂度都是$O(n^2)$

固然若是你打的是动态开点树套树就能够解决这个问题。(好像也被hack了)

因此我最慢的点也才跑0.7s可是我数组没开够

首先说明二维线段树与KD-tree的不一样:KD-tree基于读入的序列,而线段树基于值域。

KD-tree在不少状况下都要想两个儿子都要递归,而线段树向两个儿子都要递归的状况最多只会出现$log$次。

考虑一维的线段树,你查询的过程中通过的节点数一共有$log$个。

而二维的线段树两维互不干扰,这样的话它所通过的节点的控制区间就是两个一维线段树的区间自由组合,最差是$log^2$个。

因此复杂度是正确的。

作法,就是时光倒流(题目中的“Crtl+Z”有必定提示意义)。而后发现你的操做就是:

1。查找当前区间内是否还有空位置,若是有,那么ans+1。

2。把区间内全部位置设置为非空。

区间查询区间修改,不难想到线段树。

为了保证时空复杂度,须要离散化。

update操做就是若是两个儿子中都没有空位,那么你的控制区间就也没有空位了。

这样的话会出现一个问题:离散化以后两个儿子并不是紧密相邻的。

因此在离散化的时候须要加入原右端点+1来表示它是紧密相邻的。

而后就没了。代码真的好写线段树才和离散化通常长。

由于空间复杂度很高,因此须要动态开点。(不开行不行我也不知道)

它和KD-tree类似的一点就是要横着切一刀竖着切一刀这么交替的分下去。

为何不能一直竖着分,分到所须要的节点再一直横着切呢?

由于这样的话很差合并子树信息。其实不须要合并,可是合并以后至关与剪枝。

和四分树仍是不太同样的。好像网上有混淆二者概念的。

无论了,就当是我本身yy的吧。我这好像的确不叫二维线段树。

而网上说的二维线段树/四分树的单次操做复杂度最差是$O(n)$的。。。

那么你能够管我打的这个树叫Dee树。嗯。(因此Dee树就是TLE+MLE树啦)

大家能够叫我B哥。

——By Rockstar in 2018.9

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int xa[100005],xb[100005],ya[100005],yb[100005],x[300005],y[300005],X,Y,n;
 5 int qxl,qxr,qyl,qyr,lc[50000005],rc[50000005],ans=1,res,cnt,rt;char nt[50000005],u[100005];
 6 void modify(int &p,int cxl,int cxr,int cyl,int cyr,int opt){
 7     if(!p)p=++cnt;
 8     if(nt[p])return;
 9     if(qxl<=cxl&&cxr<=qxr&&qyl<=cyl&&cyr<=qyr)return nt[p]=1,ans+=res,res=0,(void)0;
10     if(opt){int mid=cxl+cxr>>1;
11         if(qxl<=mid)modify(lc[p],cxl,mid,cyl,cyr,0);
12         if(qxr>mid)modify(rc[p],mid+1,cxr,cyl,cyr,0);
13     }else{int mid=cyl+cyr>>1;
14         if(qyl<=mid)modify(lc[p],cxl,cxr,cyl,mid,1);
15         if(qyr>mid)modify(rc[p],cxl,cxr,mid+1,cyr,1);
16     }nt[p]=nt[lc[p]]&nt[rc[p]];
17 }
18 int main(){
19     freopen("excel.in","r",stdin);
20     freopen("excel.out","w",stdout);
21     scanf("%d",&n);
22     for(int i=1;i<=n;++i)scanf("%d%d%d%d",&xa[i],&ya[i],&xb[i],&yb[i]),xb[i]--,yb[i]--;
23     for(int i=1;i<=n;++i)x[i]=xa[i],x[i+n]=xb[i],x[i+n+n]=xb[i]+1,y[i]=ya[i],y[i+n]=yb[i],y[i+n+n]=yb[i]+1;
24     sort(x+1,x+1+n+n+n);sort(y+1,y+1+n+n+n);
25     X=unique(x+1,x+1+n+n+n)-x;Y=unique(y+1,y+1+n+n+n)-y;
26     for(int i=1;i<=n;++i)xa[i]=lower_bound(x+1,x+X,xa[i])-x,xb[i]=lower_bound(x+1,x+X,xb[i])-x;
27     for(int i=1;i<=n;++i)ya[i]=lower_bound(y+1,y+Y,ya[i])-y,yb[i]=lower_bound(y+1,y+Y,yb[i])-y;
28     for(int i=n;i;--i)qxl=xa[i],qxr=xb[i],qyl=ya[i],qyr=yb[i],res=1,modify(rt,1,X,1,Y,1);
29     printf("%d\n",ans);
30 }
View Code
相关文章
相关标签/搜索