2024/9/29/30

又是乌云明媚的一天。

[ARC042A] 掲示板

本来想用两个容器分别维护修改元素和未修改元素,但是遇到有重复操作的元素时会假。

看样例发现是把操作倒着输出,遇到重复元素就输出第一次出现的,其余先不管,用一个桶标记一下,最后一并输出。

因为元素和下标书写错误 WA 了一发。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int mod=1e9+7;
const int maxn=2e5+10;
const int inf=1e9+7;
int n,m,a[maxn];
bool f[maxn];
int tot,v[maxn];
signed main()
{
#ifdef Lydic
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
#endif
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		v[i]=read();
	}
	for(int i=m;i>=1;i--)
	{
		int x=v[i];
		if(!f[x]){f[x]=1;cout<<x<<endl;}
	}
	for(int i=1;i<=n;i++)
		if(!f[i])cout<<i<<endl;
	return 0;
}

山上的国度

容易发现如果存在合法的水库,那么它一定在最高点上。

所以先循环找到最高点,然后从这个点开始做一个模拟覆盖,最后检查是否有村庄未被覆盖即可。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int mod=1e9+7;
const int maxn=2e5+10;
const int inf=1e9+7;
int n,m,a[maxn];
vector<int> G[maxn];
int id,ma=-inf;
bool vis[maxn];
void dfs(int x)
{
	vis[x]=1;
	for(auto y : G[x])
	{
		if(vis[y]||a[y]>=a[x])continue;
		dfs(y);
	}
}
signed main()
{
#ifdef Lydic
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
#endif
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
		if(a[i]>ma)
		{
			ma=a[i];
			id=i;
		}
	}
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
        G[u].push_back(v);
        G[v].push_back(u);
	}
	dfs(id);
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		{
			puts("Non");
			return 0;
		}
	}
	puts("Oui, j'ai trouve la solution.");
	cout<<id;
	return 0;
}

[USACO08JAN] Running S

之前好像做过。

设一个二维 DP 状态,发现有两种转移,但是写完以后只有 30pts。

考虑到边界的问题,把转移项写到前面,发现只剩 10pts 了。

不知道怎么办,看了看题解,发现 dpi,0 的状态比较特殊,可以直接由 dpi1,0 转移过来,加上这个转移以后就可以过了。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int mod=1e9+7;
const int maxn=2e5+10;
const int inf=1e9+7;
int n,m,d[maxn];
int dp[40000][800];//第i分钟疲劳度为j
signed main()
{
#ifdef Lydic
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
#endif
	cin>>n>>m;
	for(int i=1;i<=n;i++)d[i]=read();
	dp[1][1]=d[1];
	for(int i=1;i<=n;i++)//时间
	{
		for(int j=0;j<=min(i,m);j++)//疲劳度
		{
			dp[i][0]=max(dp[i-1][0],dp[i][0]);	
			dp[i+j][0]=max(dp[i+j][0],dp[i][j]);
			dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+d[i+1]);
		}
	}
	cout<<dp[n][0];	
	return 0;
}

游览

有难度啊,说实话不知道该怎么想到这。

看上去很可以 DP,但是发现不能用拓扑排序实现。强行拓扑以后果然 WA 完了。

然后想不出来了又去看了题解,发现一个 DP 数组不够用,需要用两个数组分别表示答案和次数。

转移方程是看着很合理,但是自己想的话想不出来。

其余的是正常拓扑。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int mod=10000;
const int maxn=4e5+10;
const int inf=1e9+7;
int n,m,s,t,t0;
struct no
{
	int y,v;
};
vector<no> G[maxn];
int dp[maxn][2],du[maxn];
void topsort()
{
	queue<int> q;
	for(int i=1;i<=n;i++)
	{
		if(!du[i])
		{
			q.push(i);
			dp[i][0]=1;	
		}
	}
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(auto i : G[u])
		{
			int y=i.y,v=i.v;
			dp[y][1]=(dp[y][1]+dp[u][1]+dp[u][0]*v)%mod;
			dp[y][0]=(dp[y][0]+dp[u][0])%mod;
			if(--du[y]==0)q.push(y);
		}
	}
}
signed main()
{
#ifdef Lydic
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
#endif
	cin>>n>>m>>s>>t>>t0;
	for(int i=1;i<=m;i++)
	{
		int x=read(),y=read(),z=read();
        G[x].push_back((no){y,z});
		du[y]++;
	}
	topsort();
	cout<<(dp[t][1]+(dp[t][0]-1)*t0%mod)%mod;
	return 0;
}

[ARC125B] Squares

因为 1012=106,所以容易想到根号级别的枚举。

把题目的式子转换一下可以得到两个数的乘积的范围。我们可以枚举第一个数字,这样第二个数字的范围就确定了,然后列个小学式子计算贡献即可。

记得取模。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int mod=998244353;
const int maxn=4e5+10;
const int inf=1e9+7;
int n,k,a[maxn];
map<int,bool> mp;
void pre()
{
	mp[0]=1;
	for(int i=1;i<=1000000;i++)
	{
		mp[i*i]=1;
	}
}
signed main()
{
#ifdef Lydic
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
#endif
	pre();
	cin>>n;
	int ans=0;
	for(int i=1;i<=sqrt(n*1.0);i++)
	{
		int j=n/i;
		(ans+=(j-i)/2+1)%=mod;
	}
	cout<<ans;
	return 0;
}

[ABC218E] Destruction

翻到之前在其他号上写过题解的题。

转话题意可以得到求最小生成树。写完 WA 了,然后看见题目上有负权边。

分类讨论,把这些边全扔进答案就可以了。

点击查看代码
#include <bits/stdc++.h>
#define int long long	
using namespace std;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int mod=998244353;
const int maxn=2e6+10;
const int inf=1e9+7;
int n,m;
struct no
{
	int x,y,v;
	inline friend bool operator < (no x,no y)
	{
		return x.v<y.v;
	}
}edge[maxn];
int fa[maxn],ans,cnt,sum;
int gf(int x){return fa[x]==x?x:fa[x]=gf(fa[x]);}
signed main()
{
#ifdef Lydic
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
#endif
	cin>>n>>m;
	for(int i=1;i<=m;i++){edge[i]={read(),read(),read()};sum+=edge[i].v;}
	for(int i=1;i<=n;i++)fa[i]=i;	
	sort(edge+1,edge+m+1);
	for(int i=1;i<=m;i++)
	{
		int fx=gf(edge[i].x),fy=gf(edge[i].y);
		if(fx!=fy)
		{
			fa[fx]=fy;
            ans+=edge[i].v;
		}
		else if(edge[i].v<0)
		{
			ans+=edge[i].v;
		}
	}
	cout<<sum-ans;
	return 0;
}

[ARC071E] TrBBnsformBBtion

首先在纸上圈圈画画,发现按照要求可以把任意字符串都换成一个不超过 2 且只由 B 组成的字符串。

然后直接套个前缀和写,写完发现过了。

写题解的时候发现题读错了,但是再想想发现转化可以逆向进行,然后就完了。

点击查看代码
#include <bits/stdc++.h>
#define int long long	
using namespace std;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int inf=998244353;
const int maxn=2e6+10;
const int mod=1e9+7;
char s[maxn],t[maxn];
int sa[maxn],sb[maxn],ta[maxn],tb[maxn];
signed main()
{
#ifdef Lydic
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
#endif
	scanf("%s",s+1);
	scanf("%s",t+1);
	int n=strlen(s+1),m=strlen(t+1);
	for(int i=1;i<=n;i++)
	{
		sa[i]=sa[i-1]+(s[i]=='A');
		sb[i]=sb[i-1]+(s[i]=='B');
	}
	for(int i=1;i<=m;i++)
	{
		ta[i]=ta[i-1]+(t[i]=='A');
        tb[i]=tb[i-1]+(t[i]=='B');
	}
	int T=read();
	while(T--)
	{
		int a=read(),b=read(),x=read(),y=read();
		int l=sa[b]-sa[a-1],r=ta[y]-ta[x-1];
		// cout<<l<<' '<<r<<endl;
		l*=2;r*=2;
		l+=sb[b]-sb[a-1];r+=tb[y]-tb[x-1];
		l%=3;r%=3;
		puts(l==r?"YES":"NO");
	}
	return 0;
}

[ARC124C] LCM of GCDs

看到 n 很小,打算暴力。

由于答案完全能够枚举,所以只需要枚举答案然后检查再打擂即可。

感觉现在的绿题好水。

没了。

点击查看代码
#include <bits/stdc++.h>
#define int long long	
using namespace std;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int mod=998244353;
const int maxn=6e2+10;
const int inf=1e9+7;
int n,a[maxn],b[maxn];
vector<int> v1,v2;
int ans=0;
bool ch(int x,int y)
{
	for(int i=1;i<=n;i++)
		if((a[i]%x || b[i]%y) && (a[i]%y || b[i]%x))
			return 0;
	return 1;
}
int gcd(int x,int y){if(y==0)return x;return gcd(y,x%y);}
int lcm(int x,int y){return x*y/gcd(x,y);}
signed main()
{
#ifdef Lydic
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
#endif
	cin>>n;
	for(int i=1;i<=n;i++)a[i]=read(),b[i]=read();
	for(int i=1;i<=sqrt(a[1]*1.0);i++)
		if(a[1]%i==0)v1.push_back(i),v1.push_back(a[1]/i);
	for(int i=1;i<=sqrt(b[1]*1.0);i++)
		if(b[1]%i==0)v2.push_back(i),v2.push_back(b[1]/i);
	for(auto x : v1)
		for(auto y : v2)
			if(ch(x,y))
				ans=max(ans,lcm(x,y));
	cout<<ans;
	return 0;
}

[ARC150B] Make Divisible

题目是根号分治,除了证明没什么难的但是我看了题解

主要有几个好用的小技巧:

ab=a+b1b

以及使得 b(a+d) 的最小 d((ba)modb+b)modb

根号分治感觉挺好用的。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
	int w = 1, s = 0;
	char ch = getchar();
	while (!isdigit(ch))
	{
		if (ch == '-')
			w = -1;
		ch = getchar();
	}
	while (isdigit(ch))
	{
		s = s * 10 + (ch - '0');
		ch = getchar();
	}
	return w * s;
}
const int mod = 998244353;
const int maxn = 6e2 + 10;
const int inf = 1e9 + 7;
int T;

signed main()
{
#ifdef Lydic
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
// #else
// 	freopen("T3.in", "r", stdin);
// 	freopen("T3.out", "w", stdout);
#endif
	cerr<<((7-19)%7+7)%7<<endl;
	cin >> T;
	while (T--)
	{
		int a=read(),b=read();
		if(a>=b){printf("%lld\n",a-b);continue;}
		int ans=min(b-a,((a-b)%a+a)%a);
		if(a<=sqrt(b*1.0))
		{
			for(int x=1;x<a;x++)
			{
				int now=a+x;
				ans=min(ans,x+((now-b)%now+now)%now);
			}
		}
		else
		{
			for(int i=2;i<=a;i++)
			{
				int x=(b+i-1)/i;
				if(x>=a)
				{
					ans=min(ans,x-a+((x-b)%x+x)%x);
				}
				else break;
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}
posted @   Redamancy_Lydic  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示