ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

8.21

2022-08-22 07:31:45  阅读:149  来源: 互联网

标签:rt rll ch ll rg 8.21 define


题面和题解

A.One

线性求解约瑟夫问题.

2种解法:

方法一

维护最后一个没有出局的人在每一轮的编号.

假设一个没有出局的人上一轮的编号为id,上一轮出局的人的编号为x,那么分以下两种情况:

  1. id>x,那么id-x>0,编号为id-x;
  2. id<x,那么id-x<0,设上一轮的总人数为tot,显然id-x+tot<tot,编号即为id-x+tot.

这两种情况可以合并吗?

当然可以.当id-x>0时,它加上任何一个数再模这个数是不变的;当id-x<0时,它模上这个数一定是不变的.所以合并后上一轮的编号即为:

.

叙述成文字语言就是:

下一轮该人的编号=上一轮出局的人的编号+上一轮该人的编号.

那么代码就好理解了.

点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define rll rg ll
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
ll t,n,ans;
int main()
{
	t=read();
	while(t--)
	{
		n=read();ans=0;
		for(rll i=2;i<=n;i++) ans=(ans+n-i+1)%i;
		//加n-i+1是因为上一轮有n-i+1个人
		write(ans+1);puts("");
	}
	return 0;
}

/*标准约瑟夫环问题:
#include<stdio.h>
int main()
{
	int n,m,i,s=0;
	scanf("%d%d",&n,&m);
	for(i=2;i<=n;i++)
		s=(s+m)%i;
	printf("%d",s+1);
	return 0;
}
*/
方法二

维护当前局数1的人的位置.

具体思路就是拆环成链,把每一轮出局的人排序,最后一个出局的人在最后(实际上不需要拆环,只是为了方便理解).

先从最后一轮开始,每次往上一轮递推.由于上一轮比这一轮会多一个人,我们令当前局人数tot++,数1的人now=now+1-i,由于可能会减多(因为上一轮的人数比这一轮多1),所以让i%tot,保证为上一轮人的编号而不会越编号的界.

最后第一个数1的人是now,由于规定了最后一个出局的人在最后,所以他开始的编号就是n-now+1.

点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define rll rg ll
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
ll t,n,ans,now,tot;
int main()
{
	t=read();
	while(t--)
	{
		n=read();now=1,tot=1;
		for(rll i=n-1;i;i--)
		{
			tot++;now=now+1-i%tot;
			if(now<=0) now+=tot;
		}
		write(n-now+1);
	}
	return 0;
}

B.砖块

小模拟,模拟每次翻转的情况,把覆盖坐标加入map或者数组即可.

点击查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
#define ll int
#define rg register
#define rll rg ll
#define maxn 201
#define base 15000
#define pll pair<ll,ll>
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
ll t,n,len,ans;
ll zt,x,y;
// map<pll,short> mp;
__gnu_pbds::list_update<pll,short> mp; //O(n)复杂度的map,功能与map相同,需要#include<bits/extc++.h>库
char s[maxn];
int main()
{
	t=read();
	while(t--)
	{
		zt=x=y=ans=0;mp.clear();n=read();
		mp[(pll) { 0,0 }]=1;
		scanf("%s",s+1);len=strlen(s+1);
		for(rll i=1;i<=len;i++)
		{
			switch(s[i])
			{
			case 'N':
				if(!zt)
				{
					zt=1;y++;
					for(rll i=y;i<y+n;i++)
						mp[(pll) { x,i }]++,ans=max(ans,(ll)mp[(pll) { x,i }]);
				}
				else if(zt==1)
					zt=0,y+=n,mp[(pll) { x,y }]++,ans=max(ans,(ll)mp[(pll) { x,y }]);
				else
				{
					y++;
					for(rll i=x;i<x+n;i++)
						mp[(pll) { i,y }]++,ans=max(ans,(ll)mp[(pll) { i,y }]);
				}
				break;
			case 'S':
				if(!zt)
				{
					zt=1;y-=n;
					for(rll i=y;i<y+n;i++)
						mp[(pll) { x,i }]++,ans=max(ans,(ll)mp[(pll) { x,i }]);
				}
				else if(zt==1)
					zt=0,y--,mp[(pll) { x,y }]++,ans=max(ans,(ll)mp[(pll) { x,y }]);
				else
				{
					y--;
					for(rll i=x;i<x+n;i++)
						mp[(pll) { i,y }]++,ans=max(ans,(ll)mp[(pll) { i,y }]);
				}
				break;
			case 'W':
				if(!zt)
				{
					zt=2;x-=n;
					for(rll i=x;i<x+n;i++)
						mp[(pll) { i,y }]++,ans=max(ans,(ll)mp[(pll) { i,y }]);
				}
				else if(zt==1)
				{
					x--;
					for(rll i=y;i<y+n;i++)
						mp[(pll) { x,i }]++,ans=max(ans,(ll)mp[(pll) { x,i }]);
				}
				else
					zt=0,x--,mp[(pll) { x,y }]++,ans=max(ans,(ll)mp[(pll) { x,y }]);
				break;
			case 'E':
				if(!zt)
				{
					zt=2;x++;
					for(rll i=x;i<x+n;i++)
						mp[(pll) { i,y }]++,ans=max(ans,(ll)mp[(pll) { i,y }]);
				}
				else if(zt==1)
				{
					x++;
					for(rll i=y;i<y+n;i++)
						mp[(pll) { x,i }]++,ans=max(ans,(ll)mp[(pll) { x,i }]);
				}
				else
					zt=0,x+=n,mp[(pll) { x,y }]++,ans=max(ans,(ll)mp[(pll) { x,y }]);
				break;
			}
		}
		if(!zt)
			write(x),puts(""),write(y),puts("");
		else if(zt==1)
		{
			for(rll i=1;i<=n;i++) write(x),putchar(' ');puts("");
			for(rll i=y;i<=y+n-1;i++) write(i),putchar(' ');puts("");
		}
		else
		{
			for(rll i=x;i<x+n;i++) write(i),putchar(' ');puts("");
			for(rll i=1;i<=n;i++) write(y),putchar(' ');puts("");
		}
		write(ans);puts("");
	}
	return 0;
}

C.数字

贺的,咕咕咕
#include<bits/stdc++.h>
#define ll int
#define rg register
#define rll rg ll
#define maxn 201
#define base 10000
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
static inline void read(rg char x) { scanf("%c",&x); }
static inline void read(rg char* x) { scanf("%s",x); }
static inline void read(rg string x) { cin>>x; }
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|'0');
}
struct bigint
{
	ll s[maxn],len;
	inline void eq(rg char* ss)
	{
		memset(s,0,sizeof(s));rll l=strlen(ss);
		len=(l-1>>2)+1;
		for(rll i=1;i<len;i++) s[i]=(ss[l-(i<<2)]-'0')*1000+(ss[l-(i<<2)+1]-'0')*100+(ss[l-(i<<2)+2]-'0')*10+(ss[l-(i<<2)+3]-'0');
		for(rll i=1;i<=(l-1)%4+1;i++) s[len]=s[len]*10+(ss[i-1]-'0');
	}
	inline friend bigint operator/(rg bigint a,rll b)
	{
		for(rll i=a.len;i;i--) a.s[i-1]+=a.s[i]%b*base,a.s[i]/=b;
		while(a.len&&(!a.s[a.len])) a.len--;return a;
	}
	inline friend ll operator%(rg bigint a,rll b) { return a.s[1]%b; }
	inline bool operator<=(rll b) { return len<=1&&s[1]<=b; }
}n,m;
ll mod[]={1,10,100,1000};
ll t,k,len,num,ans;
char s[maxn];
ll jc1[maxn],jc2[maxn];
static __inline ll ksm(rll a,rll b,rll mod) { rll ans=1; a%=mod; for(rll i=b;i;i>>=1) { if(i&1) ans=ans*a%mod; a=a*a%mod; }return ans; }
static __inline ll pre(rg bigint n)
{
	if(n<=125) return jc1[n.s[1]];
	rll x=n%125;n=n/5;rll k=pre(n);n=n/25;
	return k*ksm(jc2[125],n%100,125)%125*jc2[x]%125;
}
void print(rll x,rll k)
{
	for(rll i=k;i;i--)
		if(!(x%mod[i]/mod[i-1])) putchar('0');
		else break;
	write(x%mod[k]);putn;
}
int main()
{
	jc1[0]=jc2[0]=1;
	for(rll i=1,t;i<=125;i++)
	{
		t=i;while(!(t%5)) t/=5;
		jc1[i]=jc1[i-1]*t%125;jc2[i]=jc2[i-1]*((!(i%5))?1:i)%125;
	}
	t=read();
	while(t--)
	{
		read(s);k=read();len=strlen(s);
		n.eq(s);ans=pre(n);
		if(len==1&&n.s[1]<=6)
		{
			rll t=1;for(rll i=1;i<=n.s[1];++i) t*=i;
			if(t%10==0) t/=10;
			print(t,k);continue;
		}
		m=n;num=0;
		while(m.len) m=m/5,num=(num+m%100)%100;
		ans=(ans*ksm(63,num,125))%125;
		for(rll i=0;i<=999;i+=8) if(i%125==ans) print(i,k);
	}
	return 0;
}

D.甜圈

暴力一定会T,考虑用线段树.

既然维护每一次的操作和顺序太麻烦,那么可以考虑利用哈希可以保存顺序的特点,把每次操作当成字符串,将哈希加入线段树中,维护一个区间加区间乘,最后check一下每个点的哈希是否与标准哈希(就是从1到k顺序操作计算出的哈希值)相等即可.

我不知道为什么哈希的base取7都可以过

点击查看代码
#include<bits/stdc++.h>
#ifndef ONLINE_JUDGE
#include<debug>
#endif
#define ll long long
#define rg register
#define rll rg ll
#define ull unsigned ll
#define maxn 200001
#define base 7
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
struct tree
{
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
	ull tag1,tag2;
	ull v;
	tree() { tag2=1; }
}t[maxn<<2];
ll n,k,len,T,l,r,x,ans;
ull h,stdh;
#define pushup(x) t[x].v=t[ls(x)].v+t[rs(x)].v
static inline void pushdown(rll rt,rll l,rll r)
{
	rll mid=(l+r)>>1;
	if(t[rt].tag2!=1)
	{
		t[ls(rt)].v*=t[rt].tag2;t[rs(rt)].v*=t[rt].tag2;
		t[ls(rt)].tag1*=t[rt].tag2;t[rs(rt)].tag1*=t[rt].tag2;
		t[ls(rt)].tag2*=t[rt].tag2;t[rs(rt)].tag2*=t[rt].tag2;
		t[rt].tag2=1;
	}
	if(t[rt].tag1)
	{
		t[ls(rt)].v+=t[rt].tag1*(mid-l+1);
		t[rs(rt)].v+=t[rt].tag1*(r-mid);
		t[ls(rt)].tag1+=t[rt].tag1;
		t[rs(rt)].tag1+=t[rt].tag1;
		t[rt].tag1=0;
	}
}
static inline void upd(rll rt,rll l,rll r,rll x,rll y,rg ull v)
{
	if(x<=l&&r<=y) { t[rt].v=t[rt].v*base+v*(r-l+1); t[rt].tag1=t[rt].tag1*base+v; t[rt].tag2*=base; return; }
	pushdown(rt,l,r);rll mid=(l+r)>>1;
	if(x<=mid) upd(ls(rt),l,mid,x,y,v);if(y>mid) upd(rs(rt),mid+1,r,x,y,v);
	pushup(rt);
}
static inline ull query(rll rt,rll l,rll r)
{
	if(l==r) { return (t[rt].v==stdh); }
	pushdown(rt,l,r);rll mid=(l+r)>>1;
	return query(ls(rt),l,mid)+query(rs(rt),mid+1,r);
}
int main()
{
	n=read();k=read();
	for(rll i=1;i<=k;i++)
		stdh=stdh*base+i;
	T=read();
	while(T--)
	{
		l=read();r=read();x=read();
		upd(1,1,n,l,r,x);
	}
	write(query(1,1,n));
	return 0;
}


当然数据范围是200000,用分块做更简单.只需要维护每个区间的上次操作即可.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 200001
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
ll t,n,k,len,l,r,x;
ll a[maxn],L[501],R[501],bel[maxn];
static inline void push(rll x)
{
	if(L[x])
	{
		rll tl=(x-1)*len+1,tr=min(x*len,n);
		for(rll i=tl;i<=tr;i++)
		{
			if(a[i]+1==L[x]) a[i]=R[x];
			else a[i]=-1;
		}
		L[x]=R[x]=0;
	}
}
static inline void upd(rll l,rll r,rll x)
{
	for(rll i=l;i<=r;i++)
	{
		if(a[i]+1==x) a[i]++;
		else a[i]=-1;
	}
}
int main()
{
	n=read();k=read();len=sqrt(n);
	for(rll i=1;i<=n;++i) bel[i]=(i+len-1)/len;
	t=read();
	while(t--)
	{
		l=read();r=read();x=read();
		push(bel[l]);push(bel[r]);
		if(bel[l]==bel[r]) { upd(l,r,x);continue; }
		upd(l,min(bel[l]*len,n),x);
		upd((bel[r]-1)*len+1,r,x);
		for(rll i=bel[l]+1;i<bel[r];i++)
		{
			if(L[i]!=-1)
			{
				if(!L[i]) L[i]=R[i]=x;
				else
				{
					if(R[i]+1==x) R[i]++;
					else L[i]=R[i]=-1;
				}
			}
		}
	}
	for(rll i=1;i<=bel[n];i++) push(i);
	rll ans=0;
	for(rll i=1;i<=n;i++) if(a[i]==k) ans++;
	write(ans);
	return 0;
}

标签:rt,rll,ch,ll,rg,8.21,define
来源: https://www.cnblogs.com/1Liu/p/16600166.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有