[73] (NOIP集训) NOIP2024 加赛 7
DZ:你逆元过了?
DZ:我去,那造数据的比较牛
DZ:出题人精心构造的坑,造数据的一下就给弄没了
这场真像 NOIP 难度吗,感觉还不如 CSP
两个点能对称当且仅当横坐标相等
最后统计哪个位置贡献多即可
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node{
int x,y;
};
node s[5001],x[5001];
#include<bits/extc++.h>
using namespace __gnu_pbds;
gp_hash_table<int,int>mp;
int main(){
cin>>n>>m;
for(int i=1;i<=n;++i){
cin>>s[i].x>>s[i].y;
}
for(int i=1;i<=m;++i){
cin>>x[i].x>>x[i].y;
}
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(s[i].x==x[j].x){
mp[s[i].y+x[j].y]++;
}
}
}
int ans=0;
for(auto i:mp){
ans=max(ans,i.second);
}
cout<<ans<<'\n';
}
最大独立集定义:
结论:从叶节点开始隔一层选一层最优,不用证,因为这是树,下一层的节点数量严格不低于上一层,所以这样选最优
先考虑
考虑每一层对答案的贡献就是该层的节点数目,而(以
节点数 | |
---|---|
可以发现一个以
设第一个周期的答案为
项数就是
现在的问题就变成求这一大坨等比数列,毒瘤出题人把逆元卡了(然而并没有),因此可以考虑矩阵快速幂或者倍增等方法
矩阵快速幂的写法极其简单,不难构造出初始矩阵
这是
#include<bits/stdc++.h>
#include<matrix.h>
using namespace std;
#define int long long
int n,k,p;
int a[500001];
matrix<int,4>mat,mat2;
int db(int x,int t){ //cal for 1+x+x^2+x^3+...+x^(t-1)
mat.packed_clear({
{1,0},
{1,x}
});
mat2.packed_clear({
{0,1}
});
mat.setmod(p);
mat2.setmod(p);
return (mat2*(mat|t))[1][1];
}
signed main(){
cin>>n>>k>>p;
for(int i=0;i<=k-1;++i){
cin>>a[i];
}
int s=0,sizee=1;
for(int i=0;i<=2*k-1;++i){
if((i&1)==(n&1)) s=(s+sizee)%p;
sizee=sizee*a[i%k]%p;
}
int tm=(n+1)/(2*k);
int ans=(s*db(sizee,tm)%p)%p;
sizee=power(sizee,tm);
for(int i=tm*2*k;i<=n;++i){
if((i&1)==(n&1)) ans=(ans+sizee)%p;
sizee=sizee*a[i%k]%p;
}
cout<<ans<<endl;
}
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,c,d;
int a[1000001],b[1000001];
int f[3001][3001]; //放了 i 个,其中有 j 个是红色的
signed main(){
cin>>n>>c>>d;
for(int i=1;i<=n;++i){
cin>>a[i]>>b[i];
}
for(int i=1;i<=n;++i){
for(int j=0;j<=i;++j){
if(j!=i) f[i][j]=max(f[i][j],f[i-1][j]+b[i]+c*j); //放蓝色
if(j!=0) f[i][j]=max(f[i][j],f[i-1][j-1]+a[i]+d*(i-j)); //放红色
}
}
int ans=0;
for(int i=0;i<=n;++i){
ans=max(ans,f[n][i]);
}
cout<<ans<<'\n';
}
考虑贪心,所有红色点的贡献是
考虑拆出
先假设全是蓝色点,将一个蓝色点
还有一种奇怪的写法是直接钦定所有的贡献都是红色点产生的(和前面的蓝色点产生
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,c,d;
int a[1000001],b[1000001];
int id[1000001];
inline int val(int x){
return a[x]-b[x]+(x-1)*d+(n-x)*c;
}
signed main(){
cin>>n>>c>>d;
int sum=0,ans=0;
for(int i=1;i<=n;++i){
cin>>a[i]>>b[i];
id[i]=i;
sum+=b[i];
}
ans=sum;
iota(id+1,id+n+1,1);
sort(id+1,id+n+1,[](int x,int y){return val(x)>val(y);});
for(int i=1;i<=n;++i){
sum+=val(id[i]);
ans=max(ans,sum-i*(i-1)/2*d-i*(i-1)/2*c);
}
cout<<ans<<endl;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!