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 了。
不知道怎么办,看了看题解,发现
点击查看代码
#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
因为
把题目的式子转换一下可以得到两个数的乘积的范围。我们可以枚举第一个数字,这样第二个数字的范围就确定了,然后列个小学式子计算贡献即可。
记得取模。
点击查看代码
#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
首先在纸上圈圈画画,发现按照要求可以把任意字符串都换成一个不超过 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
看到
由于答案完全能够枚举,所以只需要枚举答案然后检查再打擂即可。
感觉现在的绿题好水。
没了。
点击查看代码
#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
题目是根号分治,除了证明没什么难的但是我看了题解
主要有几个好用的小技巧:
以及使得
根号分治感觉挺好用的。
点击查看代码
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探