• 2021.03.13【NOIP提高A&B组】模拟 总结


    T1

    题目大意:从原点开始循环执行命令,问最后的位置

    好吧这就是一道幼儿园的周期问题,模拟即可

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5005;
    int T,tt,n,xx,yy,lx,ly;
    long long fx,fy;
    char op[N];
    int main() {
    	scanf("%s%d",op+1,&T);
    	n=strlen(op+1),tt=T/n;
    	for(int i=1;i<=n;i++) {
    		if(op[i]=='E')++xx;
    		else if(op[i]=='W')--xx;
    		else if(op[i]=='S')--yy;
    		else if(op[i]=='N')++yy;
    	}
    	for(int i=1;i<=(T%n);i++) {
    		if(op[i]=='E')++lx;
    		else if(op[i]=='W')--lx;
    		else if(op[i]=='S')--ly;
    		else if(op[i]=='N')++ly;		
    	}
    	fx=1LL*xx*tt+lx;
    	fy=1LL*yy*tt+ly;
    	printf("%lld %lld",fx,fy);
    }
    

    T2

    初始是 1 ,一次可以加 \(x\) 或加 \(y\) 或加 \(z\) ,问上限为 \(h\) 时最多能的到多少个数

    \(40 \ \text{pts}\) :无脑的暴力

    \(100 \ \text{pts}\)\(D_i\) 为只用 \(y,z\) 的最小\(c\mod x=i\) ,所以

    \(D_0=0\)

    \(D_{(i+y)\mod x}=D_i+y\)

    \(D_{(i+z)\mod x}=D_i+z\)

    这样可以用最短路来转移。答案就是 \(\sum_{i=0}^{x-1}(\lfloor\dfrac{h-D_i}{x}\rfloor+1)*(n\ge D_i)\)

    剩下的 \(h-D_i\) 都只用 \(x\) ,就有 \(\lfloor\dfrac{h-D_i}{x}\rfloor\) ,还可以不用 \(x\) ,所以加一

    2021.3.15 19:46 发现这是一题经典的同余最短路

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=100005;
    LL n,res,dis[N];
    int x,y,z,cnt,l,r,q[N],vis[N];
    int main() {
    	scanf("%lld%d%d%d",&n,&x,&y,&z),--n;
    	memset(dis,100,sizeof(dis));
    	dis[0]=0,q[r=1]=0;
    	for(int u,v;l<r;) {
    		u=q[++l],vis[u]=0;
    		if(dis[u]+y<dis[v=(u+y)%x])dis[v]=dis[u]+y,q[++r]=v;
    		if(dis[u]+z<dis[v=(u+z)%x])dis[v]=dis[u]+z,q[++r]=v;
    	}
    	for(int i=0;i<x;i++)
    		if(n>=dis[i])res+=(n-dis[i])/x+1;
    	printf("%lld",res);
    } 
    

    T3

    题意:维护一个序列,操作 1 把 \(L\le\forall i\le R\) 的元素加上 \(F_{i-L+1}\) 其中 \(F\) 表示斐波那契数列

    良心的暴力分:\(40\),折腾一个小时线段树的结果

    赛后:我*,懒标记可以用 vector !!!为什么不会超时:我也不知道

    然后线段树巨大常数会超时,用分块。下传标记、修改、查询都是 \(O(\sqrt n)\) ,总 \(O(m\sqrt n)\)

    #include<bits/stdc++.h>
    #define RG register
    using namespace std;
    typedef long long LL;
    const LL P=1000000009;
    const int N=100005,SQ=1005; 
    inline int Rd() {
    	RG int x=0;
    	char C=getchar();
    	for(;C<'0'||C>'9';C=getchar()) ;
    	for(;C>'/'&&C<':';C=getchar()) x=(x<<1)+(x<<3)+(C^48);
    	return x;
    }
    LL x[N],sm[SQ],ans,f[N]={0,1,1},s[N]={0,1,2};
    vector<int>tg[SQ];
    int n,T,pos[N],L[SQ],R[SQ],bl; 
    inline void down(RG int p) {
    	if(tg[p].empty())return;
    	for(RG int i=0;i<tg[p].size();i++)
    		for(RG int j=L[p];j<=R[p];j++)
    			(x[j]+=f[j-tg[p][i]+1])%=P;
    	tg[p].clear();
    }
    inline void mdy(RG int l,RG int r) {
    	RG int p=pos[l],q=pos[r];
    	if(p==q) {
    		for(RG int i=l;i<=r;i++)
    			(x[i]+=f[i-l+1])%=P,
    			(sm[p]+=f[i-l+1])%=P;
    		return;
    	}
    	for(RG int i=l;i<=R[p];i++)
    		(x[i]+=f[i-l+1])%=P,
    		(sm[p]+=f[i-l+1])%=P;
    	for(RG int i=p+1;i<=q-1;i++)
    		(sm[i]+=(s[R[i]-l+1]-s[L[i]-l]+P)%P)%=P,
    		tg[i].push_back(l);
    	for(RG int i=L[q];i<=r;i++)
    		(x[i]+=f[i-l+1])%=P,
    		(sm[q]+=f[i-l+1])%=P;
    }
    inline void ask(RG int l,RG int r) {
    	RG int p=pos[l],q=pos[r];
    	if(p==q) {
    		down(p);
    		for(RG int i=l;i<=r;i++)(ans+=x[i])%=P;
    		return;
    	}
    	down(p),down(q);
    	for(RG int i=l;i<=R[p];i++)(ans+=x[i])%=P;
    	for(RG int i=p+1;i<=q-1;i++)(ans+=sm[i])%=P;
    	for(RG int i=L[q];i<=r;i++)(ans+=x[i])%=P;
    }
    int main() {
    	n=Rd(),T=Rd();
    	for(RG int i=3;i<=n;i++)
    		f[i]=(f[i-1]+f[i-2])%P,
    		s[i]=(s[i-1]+f[i])%P;
    	for(RG int i=1;i<=n;i++)x[i]=1LL*Rd();
    	bl=sqrt(1.0*n);
    	for(RG int i=1;i<=bl;i++)L[i]=R[i-1]+1,R[i]=i*bl;
    	if(R[bl]<n)++bl,L[bl]=R[bl-1]+1,R[bl]=n;
    	for(RG int i=1;i<=bl;i++)
    		for(RG int j=L[i];j<=R[i];j++)
    			pos[j]=i,(sm[i]+=x[j])%=P;
    	for(RG int opt,l,r;T--;) {
    		opt=Rd(),l=Rd(),r=Rd();
    		if(opt==1)mdy(l,r);
    		else ans=0,ask(l,r),printf("%lld\n",ans);
    	}
    }
    
    

    方法 2

    维护一个贡献数组 \(d\) ,可以 \(O(1)\) 修改:

    \(d_l\leftarrow d_l+1\)

    \(d_{r+1}\leftarrow d_{r+1}-f_{r-l+2}\)

    \(d_{r+2}\leftarrow d_{r+2}-f_{r-l+1}\)

    重算:\(O(n)\) 计算 \(d\) ,即对原数组的贡献 \(d_i=d_{i-1}+d_{i-2}\)

    但是这样复杂度依然不理想,发现瓶颈是重算

    运用平衡规划(好高级的样子),每 \(k\) 次进行重算

    发现询问时不一定刚刚重算完,所以这一段贡献单独算进答案

    容易发现当 \(k=\sqrt m\) 时复杂度最优,为 \(O((n+m)\sqrt m)\)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL P=1000000009;
    const int N=100005;
    int n,T,bl,ls=1,opt[N],l[N],r[N];
    LL res,x[N],sm[N],d[N],f[N]={0,1,1},s[N]={0,1,2};
    int main() {
    	scanf("%d%d",&n,&T);
    	for(int i=3;i<=n;i++) {
    		f[i]=(f[i-1]+f[i-2])%P;
    		s[i]=(s[i-1]+f[i])%P;
    	}
    	for(int i=1;i<=n;i++) {
    		scanf("%d",&x[i]);
    		sm[i]=(sm[i-1]+x[i])%P;
    	}
    	bl=sqrt(1.0*T);
    	for(int i=1;i<=T;i++) {
    		scanf("%d%d%d",&opt[i],&l[i],&r[i]);
    		if(opt[i]==1) {
    			++d[l[i]];
    			d[r[i]+1]-=f[r[i]-l[i]+2];
    			d[r[i]+2]-=f[r[i]-l[i]+1];
    		} else {
    			res=(sm[r[i]]-sm[l[i]-1]+P)%P;
    			for(int j=ls;j<=i;j++)
    				if(opt[j]==1 && r[j]>=l[i] && l[j]<=r[i])
    					res=(res+s[min(r[i],r[j])-l[j]+1]-s[max(l[i],l[j])-l[j]]+P)%P;
    			printf("%lld\n",res);
    		}
    		if(i%bl==0) {
    			sm[1]=(x[1]+=d[1]),ls=i+1;
    			for(int j=2;j<=n;j++) {
    				(d[j]+=d[j-1]+d[j-2]+P)%=P;
    				(x[j]+=d[j]+P)%=P;
    				sm[j]=(sm[j-1]+x[j])%P;
    			}
    			memset(d,0,sizeof(d));
    		}
    	}
    } 
    

    T4

    赛时:怎么又是期望 dp ,放弃了

    赛后:三行代码认真的吗?

    其实就是把相邻两个数的较大值取倒数,然后求和

    #include<bits/stdc++.h>
    using namespace std;
    const int N=10000005;
    int n,A,B,C,x[N];
    double s;
    int main() {
    	scanf("%d%d%d%d%d",&n,&A,&B,&C,x+1);
    	for(int i=2;i<=n;i++)
    		x[i]=(1LL*x[i-1]*A+1LL*B)%100000001;
    	for(int i=1;i<=n;i++)x[i]=x[i]%C+1;
    	for(int i=1;i<=n;i++)s+=1.0/max(x[i],x[i%n+1]);
    	printf("%.3lf",s);
    } 
    

    总结

    T2:了解了同余最短路,希望下次知道

    T3:原来懒标记可以这样+奇妙的差分+平衡规划

    T4:不要以为期望 dp 很难

  • 相关阅读:
    第一次上传文件到linux服务器
    @JsonFormat与@DateTimeFormat的区别
    Tomcat端口被占用处理
    简单的Tomcat部署
    PHP源码加密,zend guard与ioncube
    PHP计算年龄
    My97DatePicker时间控件 JQuery UI
    php二维数组自定义排序
    CodeSmith Generator 7.0.2激活步骤
    SQL Server Management Studio 2008版本的安装
  • 原文地址:https://www.cnblogs.com/KonjakLAF/p/14539726.html
Copyright © 2020-2023  润新知