Codeforces 1106 简要题解
A题
传送门
读错题还能过样例我给自己点个赞。
题意简述:给一个010101网格SSS,问满足Si,j=Si+1,j+1=Si+1,j−1=Si−1,j−1=Si−1,j+1S_{i,j}=S_{i+1,j+1}=S_{i+1,j-1}=S_{i-1,j-1}=S_{i-1,j+1}Si,j=Si+1,j+1=Si+1,j−1=Si−1,j−1=Si−1,j+1的XXX型个数,边长≤500‘在这里插入代码片‘\le500`在这里插入代码片`≤500‘在这里插入代码片‘。
直接模拟好吧别问博主是怎么看错题的
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
typedef long long ll;
const int N=505;
int n;
char s[N][N];
int main(){
scanf("%d",&n);
for(ri i=1;i<=n;++i)scanf("%s",s[i]+1);
int ans=0;
for(ri i=2;i<n;++i)for(ri j=2;j<n;++j){
if(s[i][j]=='X'&&s[i+1][j+1]=='X'&&s[i-1][j+1]=='X'&&s[i-1][j-1]=='X'&&s[i+1][j-1]=='X')++ans;
}
cout<<ans;
return 0;
}
B题
传送门
题意简述:现在有nnn个物品,每个物品有剩余体积和单位体积所需价格。
现在有mmm个人依次来买物品,先买他指定的,如果不够就从最便宜的物品开始补,补到满足这个人需求量或者所有物品都没有为止,问每个人花费。
直接模拟,难点在于英语阅读,考虑用堆来维护每个物品的信息,这样摊下来时间复杂度是很正常的O(logn)O(logn)O(logn),毕竟每个物品最多删掉一次。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
typedef long long ll;
const int N=1e5+5;
int n,m,mp[N];
struct Node{int a,b,id;}p[N];
inline bool cmp(const Node&a,const Node&b){return a.b<b.b||(a.b==b.b&&a.id<b.id);}
priority_queue<Node>q;
inline bool operator<(const Node&a,const Node&b){return a.b>b.b||(a.b==b.b&&a.id>b.id);}
int main(){
n=read(),m=read();
for(ri i=1;i<=n;++i)p[i].a=read();
for(ri i=1;i<=n;++i)p[i].b=read(),p[i].id=i;
sort(p+1,p+n+1,cmp);
for(ri i=1;i<=n;++i)mp[p[i].id]=i,p[i].id=i,q.push(p[i]);
while(m--){
int t=read(),d=read();
if(p[mp[t]].a>=d){
p[mp[t]].a-=d;
cout<<(ll)d*p[mp[t]].b<<'\n';
continue;
}
ll res=(ll)p[mp[t]].a*p[mp[t]].b;
d-=p[mp[t]].a,p[mp[t]].a=0;
while(d&&!q.empty()){
Node tmp=q.top();
if(!p[tmp.id].a)q.pop();
else{
if(p[tmp.id].a>=d){
p[tmp.id].a-=d;
res+=(ll)p[tmp.id].b*d;
d=0;
}
else{
res+=(ll)p[tmp.id].a*p[tmp.id].b;
d-=p[tmp.id].a,p[tmp.id].a=0;
q.pop();
}
}
}
if(d)cout<<0<<'\n';
else cout<<res<<'\n';
}
return 0;
}
C题
传送门
题意简述:给nnn个数让分成若干组(每组至少两个数),一组的代价是组内左右数之和的平方,问总代价最小值。
思路:
显然的一道贪心,把数列排序之后一头一尾配对即可。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
typedef long long ll;
const int N=3e5+5;
int n,a[N];
ll ans=0;
int main(){
n=read();
for(ri i=1;i<=n;++i)a[i]=read();
sort(a+1,a+n+1);
for(ri i=1;i+i<=n;++i)ans+=(ll)(a[i]+a[n-i+1])*(a[i]+a[n-i+1]);
cout<<ans;
return 0;
}
D题
传送门
题意简述:给一张无向图,一个人从1号点出发,每次经过一个点时,如果是第一次经过某个点就把这个点加入一个序列中,问最后得到的序列的最小字典序。
思路:我们用一个堆来维护所有点的进出顺序即可,每次弹出一个点时把它能到的所有没入堆的点都压进堆里面,然后每次弹出编号最小的点即可。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
typedef long long ll;
const int N=1e5+5;
int n,m;
vector<int>e[N];
bool vis[N];
void bfs(){
priority_queue<int,vector<int>,greater<int> >q;
q.push(1);
vis[1]=1;
while(!q.empty()){
int x=q.top();
q.pop();
cout<<x<<' ';
for(ri i=0,v;i<e[x].size();++i){
if(vis[v=e[x][i]])continue;
vis[v]=1,q.push(v);
}
}
}
int main(){
n=read(),m=read();
for(ri i=1,u,v;i<=m;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
bfs();
return 0;
}
E题
传送门
题意简述:现在有kkk个钱包,nnn个时间点,每个钱包有四个属性s,t,d,ws,t,d,ws,t,d,w表示这个钱包只能在时间点[s,t][s,t][s,t]捡,价值为www,并且如果在某个时间点捡了这个红包在时间点ddd之后才能够捡下一个红包,现在可以强制mmm个时间点不能捡红包,一个人会贪心从第一个时间点开始捡红包(即对于当前时间点如果能捡红包以价格为第一关键字ddd为第二关键字捡红包)问他能获得的最小收益。
思路:设fi,jf_{i,j}fi,j表示在前iii个时间点加jjj次限制获得的最小收益。
然后我们用线段树预处理出每个时间点如果可以选择应该选择捡哪一个红包,然后直接转移即可。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
typedef long long ll;
const int N=1e5+5,M=205;
int n,m,k;
ll f[N][M];
struct Node{int s,t,d,w;}a[N];
typedef pair<int,int> pii;
pii pre[N];
namespace SGT{
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (l+r>>1)
pii val[N<<2]=pii(0,0);
inline void update(int p,int l,int r,int ql,int qr,pii v){
if(ql<=l&&r<=qr){val[p]=max(val[p],v);return;}
if(qr<=mid)update(lc,l,mid,ql,qr,v);
else if(ql>mid)update(rc,mid+1,r,ql,qr,v);
else update(lc,l,mid,ql,mid,v),update(rc,mid+1,r,mid+1,qr,v);
}
inline void query(int p,int l,int r,pii v){
v=max(v,val[p]);
if(l==r){pre[l]=v;return;}
query(lc,l,mid,v),query(rc,mid+1,r,v);
}
}
inline void update(ll&a,const ll&b){a=a<b?a:b;}
int main(){
n=read(),m=read(),k=read();
for(ri i=1;i<=k;++i){
a[i].s=read(),a[i].t=read(),a[i].d=read(),a[i].w=read();
SGT::update(1,1,n,a[i].s,a[i].t,pii(a[i].w,a[i].d));
}
for(ri i=0;i<=n+1;++i)for(ri j=0;j<=m+1;++j)f[i][j]=1e18;
SGT::query(1,1,n,pii(0,0)),f[0][0]=0;
for(ri i=1;i<=n;++i)cerr<<pre[i].first<<' '<<pre[i].second<<'\n';
for(ri j=0;j<=m;++j){
for(ri i=0;i<=n;++i){
update(f[i+1][j+1],f[i][j]);
if(pre[i]==pii(0,0))update(f[i+1][j],f[i][j]);
else update(f[pre[i].second+1][j],f[i][j]+pre[i].first);
}
}
ll ans=1e18;
for(ri i=0;i<=m;++i)update(ans,f[n+1][i]);
return cout<<ans,0;
}
F题
传送门
题意简述:原本有一个fff数列,满足∀i>k,fi=(∏j=1kfi−jbj)mod  P,P=998244353\forall i>k,f_i=(\prod_{j=1}^kf_{i-j}^{b_j})\mod P,P=998244353∀i>k,fi=(∏j=1kfi−jbj)modP,P=998244353,现在已知f1f_1f1~fk−1=1f_{k-1}=1fk−1=1,以及fn(n≥k)=mf_n(n\ge k)=mfn(n≥k)=m,求fkf_kfk的可能值。
思路:
先考虑没有模数的做法:
由于f1f_1f1~fk−1f_{k-1}fk−1都是111,因此fk+1f_{k+1}fk+1是fkf_kfk的幂,fk+2f_{k+2}fk+2是fkf_kfk的幂,…,fn=mf_n=mfn=m是fkf_kfk的幂,这启发我们把f1f_1f1 ~ fk−1f_{k-1}fk−1都看成(fk)0(f_k)^0(fk)0,于是我们可以矩阵快速幂递推出m=fn=(fk)pm=f_n=(f_k)^pm=fn=(fk)p。
然后考虑同时取离散对数。
这样令ggg为原根,fk=gk,m=gq=>(gk)p=gq=>pk≡qmod  (P−1)f_k=g^k,m=g^q=>(g^k)^p=g^q=>pk\equiv q\mod (P-1)fk=gk,m=gq=>(gk)p=gq=>pk≡qmod(P−1)
然后就只用分别把p,qp,qp,q解出来然后跑一遍exgcdexgcdexgcd即可。
代码:
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define ri register int
using namespace std;
const int mod=998244353,mod1=998244352,N=105,Mod=1e6+7;
int k,b[N],n,m;
typedef long long ll;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
inline int mul(int a,int b){return (ll)a*b%mod;}
inline int add1(int a,int b){return a+b>=mod1?a+b-mod1:a+b;}
inline int dec1(int a,int b){return a>=b?a-b:a-b+mod1;}
inline int mul1(int a,int b){return (ll)a*b%mod1;}
struct Matrix{
int a[N][N];
Matrix(int val=0){memset(a,0,sizeof(a));for(ri i=0;i<k;++i)a[i][i]=val;}
friend inline Matrix operator*(const Matrix&a,const Matrix&b){
Matrix ret(0);
for(ri i=0;i<k;++i)for(ri l=0;l<k;++l)if(a.a[i][l])
for(ri j=0;j<k;++j)ret.a[i][j]=add1(ret.a[i][j],mul1(a.a[i][l],b.a[l][j]));
return ret;
}
friend inline Matrix operator^(Matrix a,int p){
Matrix ret(1);
for(;p;p>>=1,a=a*a)if(p&1)ret=ret*a;
return ret;
}
}a;
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;}
inline int query(){
int sqr=sqrt(mod);
int tmp=ksm(3,sqr);
tr1::unordered_map<int,int>S;
S.clear();
for(ri i=0,mult=m,inv=ksm(3,mod-2);i<sqr;++i,mult=mul(mult,inv))S[mult]=i+1;
for(ri i=0,mult=1,stp=ksm(3,sqr);i*sqr<=mod;++i,mult=mul(mult,stp))if(S[mult])return (S[mult]-1)+i*sqr;
return -1;
}
inline void exgcd(int a,int b,int&x,int&y){
if(!b){x=1,y=0;return;}
exgcd(b,a-a/b*b,x,y);
int t=x;
x=y,y=t-a/b*y;
}
int main(){
scanf("%d",&k);
int sum=0;
for(ri i=1;i<=k;++i)scanf("%d",&b[i]),sum=add1(sum,b[i]);
scanf("%d%d",&n,&m);
for(ri i=1;i<k;++i)a.a[i][i-1]=1;
for(ri i=0;i<k;++i)a.a[i][k-1]=b[k-i];
for(ri i=0;i<k;++i,puts(""))for(ri j=0;j<k;++j)cerr<<a.a[i][j]<<' ';
a=a^(n-k);
for(ri i=0;i<k;++i,puts(""))for(ri j=0;j<k;++j)cerr<<a.a[i][j]<<' ';
int p=a.a[k-1][k-1];
int q=query();
if(q==-1)return puts("-1"),0;
int x,y,a=p,b=mod1,c=q,g=__gcd(a,b);
if(c%g)return puts("-1"),0;
a/=g,b/=g,c/=g,exgcd(a,b,x,y);
x=(x%mod1+mod1)%mod1,x=(ll)x*c%mod1;
cout<<ksm(3,x);
return 0;
}
Codeforces 1106 简要题解的更多相关文章
- Codeforces 863 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...
- Codeforces 381 简要题解
做的太糟糕了...第一题看成两人都取最优策略,写了个n^2的dp,还好pre-test良心(感觉TC和CF的pretest还是很靠谱的),让我反复过不去,仔细看题原来是取两边最大的啊!!!前30分钟就 ...
- Codeforces 1120 简要题解
文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述:给你一个mmm个数的数列,现在规定把一个数列的1,2,...,k1,2,...,k1,2,...,k分成第一组,把k+1, ...
- Codeforces 1098 简要题解
文章目录 前言 A题 B题 C题 D题 E题 传送门 前言 没错因为蒟蒻太菜了这场的最后一道题也咕掉了,只有AAA至EEE的题解233 A题 传送门 题意简述:给出一棵带点权的树,根节点深度为111, ...
- Codeforces 1110 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 众所周知ldxoildxoildxoi这种菜鸡选手是不会写HHH题的,因此该篇博客只有AAA题至GGG题的题解,实在抱歉. A题 传送门 题 ...
- Codeforces 380 简要题解
ABC见上一篇. 感觉这场比赛很有数学气息. D: 显然必须要贴着之前的人坐下. 首先考虑没有限制的方案数.就是2n - 1(我们把1固定,其他的都只有两种方案,放完后长度为n) 我们发现对于一个限制 ...
- Codeforces 845 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意:2n2n2n个人下棋,分为两个阵营,每个阵营nnn个人,每个人有一个积分,积分高的能赢积分低的,问如果你可以随意选人,然 ...
- Codeforces 1065 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 GGG题略难,膜了一波zhouyuyang{\color{red} zhouyuyang}zhouyuyang巨佬的代码. 其余都挺清真的. ...
- Codeforces 888 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意简述:给一个数列,问有多少个峰值点(同时比两边都大/小的点) 思路:按照题意模拟. 代码: #include<bit ...
随机推荐
- 在.NET 4中用IIS部署WCF就这么简单
在.NET 3.5中,我们需要这样做: 1. 添加一个HelloService.svc文件,添加ServiceHost标记,在Service中添加WCF服务实现的名称,比如: <%@ Servi ...
- POJ-1426.Findthemultiple.(BFS)
一开始模拟了一波大数取余结果超时了,最后改成long long过了emmm... 本题大意:给出一个200以内的数n,让你找出一个m使得m % n == 0,要求m只有1和0组成. 本题思路:BFS模 ...
- Linux基石【第三篇】vim提示-bash:vim :common not found解决方法
在Linux命令行输入vim时提示:-bash:vim :common not found,之后按着查询到的解决办法整好了: 解决步骤如下: 1.输入 rpm -qa|grep vim 命令,查看返回 ...
- 《基于Nginx的中间件架构》学习笔记---1.环境配置
一.环境调试确认 (四项确认) 1.确认系统网络 ping www.baidu.com 2.确认yum可用 yum list|grep gcc 3.确认关闭iptables规则 iptables -L ...
- DBCO
实现SAP连接外部数据库 也可用SM30维护DBCON的内容 SAP提供了对原生sql的操作,主要有以下几个类组成: CL_SQL_STATEMENT - Execution of SQL State ...
- go语言中的接口interface
package main; import "fmt" //接口interface //接口是一个或多个方法签名的集合 //只要某个类型拥有该接口的所有方法签名,即算实现该接口. / ...
- StackExchange.Redis使用以及封装
来源:http://www.cnblogs.com/qtqq/p/5951201.html Redis安装:http://www.runoob.com/redis/redis-install.html ...
- IIS站点报拒绝访问Temporary ASP.NET Files的解决办法
IIS站点本来运行的好好的,突然就出现了:Temporary ASP.NET Files拒绝访问的问题.遇到此类问题,请逐步排查,定可解决. 原因:Windows操作系统升级导致. 办法: 1.检查C ...
- 10.23JS日记
1.逻辑运算 || && ! ||:遇到第一个为true的值就中止并返回 &&:遇到第一个为false的值就中止并返回,如果没有false值,就返回最后一个不是fa ...
- Vs2015 c# 诊断工具查看程序的占用情况
windbg用着还不熟悉,dottrace 还要版权,着急查看程序的cpu 的使用情况,因为程序开启之后占用处理器资源较大,问题在哪里呢,于是点开了vs2015自带的诊断工具,以前偶尔打开过,没发现 ...