Codeforces 1114 简要题解
传送门
然而这场div2div2div2没有什么难度比较大的题
A题
传送门
题意简述:三个人分别至少选x,y,zx,y,zx,y,z件物品,有三种物品数量分别为a,b,ca,b,ca,b,c,其中第一个人只能选第一种,第二个人不能选第三种,第三个人随意问能否满足三个人需求。
思路:
直接模拟即可。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+5,mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline int read(){
int ans=0,w=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans*w;
}
int x,y,z,a,b,c;
int main(){
x=read(),y=read(),z=read(),a=read(),b=read(),c=read();
if(x>a)return puts("NO"),0;
a-=x;
a+=b;
if(y>a)return puts("NO"),0;
a-=y,a+=c;
if(z>a)return puts("NO"),0;
puts("YES");
return 0;
}
B题
传送门
题意简述:
要求把nnn个数的数列分成kkk份,每份至少有mmm个数,问这kkk份的前mmm大数之和的和最大值是多少,并要求给出一种构造方案。
思路:
显然可以构造出一种方案满足所有组的前mmm大拼起来是整个数列的前k∗mk*mk∗m大,排序分组即可。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+5,mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline int read(){
int ans=0,w=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans*w;
}
int n,m,k;
struct Node{int val,id;}a[N];
inline bool cmp1(const Node&a,const Node&b){return a.val>b.val;}
inline bool cmp2(const Node&a,const Node&b){return a.id<b.id;}
int main(){
n=read(),m=read(),k=read();
for(ri i=1;i<=n;++i)a[i].val=read(),a[i].id=i;
sort(a+1,a+n+1,cmp1);
ll ans=0;
for(ri i=1;i<=k*m;++i)ans+=a[i].val;
cout<<ans<<'\n';
sort(a+1,a+k*m+1,cmp2);
for(ri i=m;i<k*m;i+=m)cout<<a[i].id<<' ';
return 0;
}
C题
传送门
题意简述:给出 两个数n,b,n≤1e18,b≤1e12n,b,n\le1e18,b\le1e12n,b,n≤1e18,b≤1e12,问n!n!n!在bbb进制下有多少个后缀000。
思路:
令b=a1k1a2k2...apkpb=a_1^{k_1}a_2^{k_2}...a_p^{k_p}b=a1k1a2k2...apkp
然后算算n!n!n!中分别有多少个a1,a2,...,apa_1,a_2,...,a_pa1,a2,...,ap,算出来之后除以kpk_pkp更新答案即可。
注意不要爆long long
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+5,mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline ll read(){
ll ans=0,w=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans*w;
}
ll n,b;
inline ll calc(ll n,ll x,ll tim){
ll res=0,ret=0;
for(ll mul=x;mul<=n;mul*=x){
ret+=n/mul;
res+=ret/tim,ret%=tim;
if(mul>n/x)break;
}
return res;
}
inline ll solve(ll n,ll p){
ll res=2e18,up=p;
for(ri i=2;(ll)i*i<=up;++i){
if(p!=p/i*i)continue;
ll cnt=0;
while(p==p/i*i)p/=i,++cnt;
res=min(res,calc(n,i,cnt));
}
if(p^1)res=min(res,calc(n,p,1));
return res;
}
int main(){
n=read(),b=read();
cout<<solve(n,b);
return 0;
}
D题
传送门
题意简述:给出一个nnn个数的数列(n≤5000)(n\le5000)(n≤5000),称一段相同的数为一个连通块,你每次可以选择一个连通块把它整体变成另一个数,问把整个数列变成同一个数的最少次数。
思路:先把连通块压成一个数,然后区间dpdpdp转移一下即可。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=5005,mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline ll read(){
ll ans=0,w=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans*w;
}
inline void update(int&a,const int&b){a=b<a?b:a;}
int n,c[N],tot=0,f[N][N];
int main(){
n=read();
for(ri i=1;i<=n;++i)c[i]=read();
for(ri i=1;i<=n;++i)if(c[i]^c[tot])c[++tot]=c[i];
n=tot;
memset(f,0x3f,sizeof(f));
for(ri i=1;i<=n;++i)f[i][i]=0;
for(ri len=2;len<=n;++len){
for(ri l=1,r=l+len-1;r<=n;++l,++r){
if(c[l]==c[r])update(f[l][r],f[l+1][r-1]+1);
update(f[l][r],1+f[l+1][r]);
update(f[l][r],f[l][r-1]+1);
}
}
cout<<f[1][n];
return 0;
}
E题
传送门
题意简述:交互题。
现在有一个nnn个数的n≤1e6n\le1e6n≤1e6的打乱顺序的等差数列,保证ai≤1e9,公差>0a_i\le1e9,公差>0ai≤1e9,公差>0,你可以问不超过606060次来找到这个数列的首项和公差。
你可以问的问题如下:
- > x>\ x> x:询问数列是否存在一个数>x>x>x,存在返回111否则返回000。
- ? x?\ x? x:询问数列第xxx个数的值(打乱后的第xxx个)。
思路:先问第一种问题303030次找到数列的最大值,然后随机出一些位置求它们跟最大值差值的gcdgcdgcd作为公差。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,ll> pii;
const int N=4e5+5,mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
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 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;
}
int n,mx,d,mn;
map<int,int>mp;
int main(){
srand(time(NULL));
n=read();
int l=0,r=1e9,mx=1e9;
int tim=0;
while(l<=r){
int mid=l+r>>1;
cout<<"> "<<mid<<endl<<endl;
if(read())l=mid+1;
else r=mid-1,mx=mid;
}
int d=0;
for(ri x,i=1;i<=min(29,n);++i){
while(1){
x=(ll)rand()*rand()%n+1;
if(!mp[x]){mp[x]=1;break;}
}
cout<<"? "<<x<<endl<<endl;
x=read();
d=__gcd(d,mx-x);
}
cout<<"! "<<mx-(n-1)*d<<' '<<d<<endl<<endl;
return 0;
}
F题
传送门
题意简述:现在有一个长度为nnn的数列n≤4e5n\le4e5n≤4e5,数列里的数最开始≤300\le300≤300,现在要求支持如下操作:
- 区间乘一个数v≤300v\le300v≤300
- 求区间数的乘积的欧拉函数值。
询问数≤2e5\le2e5≤2e5,答案对1e9+71e9+71e9+7取模。
思路:询问操作相当于问的是这个东西:Mull,r∗∏primei,primei is a factor of Mul[l,r]primei−1primeiMul_{l,r}*\prod_{prime_i,prime_i\ is\ a\ factor\ of\ Mul_{[l,r]}} \frac{prime_i-1}{prime_i}Mull,r∗∏primei,primei is a factor of Mul[l,r]primeiprimei−1
前面的积可以用线段树维护,考虑到300300300以内的素数只有626262个,我们把它们的存在性用一个longlonglong longlonglong压起来再用线段树维护即可。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,ll> pii;
const int N=4e5+5,mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
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 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;
}
int pri[305],invp[305],n,q,tot=-1;
bool vis[305];
inline void init(){
for(ri i=2;i<=300;++i){
if(!vis[i])pri[++tot]=i,invp[tot]=ksm(i,mod-2);
for(ri j=0;j<=tot&&i*pri[j]<=300;++j){
vis[i*pri[j]]=1;
if(i==i/pri[j]*pri[j])break;
}
}
}
inline ll solve(int val){
ll ret=0;
for(ri i=0;i<=tot;++i)if(val==val/pri[i]*pri[i])ret|=1ll<<i;
return ret;
}
namespace SGT{
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (l+r>>1)
int val[N<<2],lz1[N<<2],len[N<<2];
ll exi[N<<2],lz2[N<<2];
inline void pushup(int p){val[p]=mul(val[lc],val[rc]),exi[p]=exi[lc]|exi[rc];}
inline void pushnow(int p,int v1,ll v2){val[p]=mul(val[p],ksm(v1,len[p])),exi[p]|=v2,lz1[p]=mul(lz1[p],v1),lz2[p]|=v2;}
inline void pushdown(int p){if(lz1[p]==1&&!lz2[p])return;pushnow(lc,lz1[p],lz2[p]),pushnow(rc,lz1[p],lz2[p]),lz1[p]=1,lz2[p]=0;}
inline void build(int p,int l,int r){
lz1[p]=1,lz2[p]=0,len[p]=r-l+1;
if(l==r){exi[p]=solve((val[p]=read()));return;}
build(lc,l,mid),build(rc,mid+1,r),pushup(p);
}
inline void update(int p,int l,int r,int ql,int qr,int v1,ll v2){
if(ql<=l&&r<=qr)return pushnow(p,v1,v2);
pushdown(p);
if(qr<=mid)update(lc,l,mid,ql,qr,v1,v2);
else if(ql>mid)update(rc,mid+1,r,ql,qr,v1,v2);
else update(lc,l,mid,ql,mid,v1,v2),update(rc,mid+1,r,mid+1,qr,v1,v2);
pushup(p);
}
inline pii query(int p,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return pii(val[p],exi[p]);
pushdown(p);
if(qr<=mid)return query(lc,l,mid,ql,qr);
if(ql>mid)return query(rc,mid+1,r,ql,qr);
pii a=query(lc,l,mid,ql,mid),b=query(rc,mid+1,r,mid+1,qr);
return pii(mul(a.fi,b.fi),a.se|b.se);
}
}
inline int calc(int v1,ll v2){
for(ri i=0;i<=tot;++i)if((v2>>i)&1)v1=mul(v1,mul(pri[i]-1,invp[i]));
return v1;
}
int main(){
init(),n=read(),q=read();
SGT::build(1,1,n);
char s[10];
for(ri tt=q,l,r,x;tt;--tt){
scanf("%s",s),l=read(),r=read();
if(s[0]=='T'){
pii tmp=SGT::query(1,1,n,l,r);
cout<<calc(tmp.fi,tmp.se)<<'\n';
}
else x=read(),SGT::update(1,1,n,l,r,x,solve(x));
}
return 0;
}
Codeforces 1114 简要题解的更多相关文章
- 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 ...
随机推荐
- css 实现多行文本末尾显示省略号
思路: 省略号使用绝对定位添加,开头部分避免突兀使用c3渐变背景颜色 <!DOCTYPE html> <html lang="en"> <head&g ...
- μC/Probe尝鲜
μC/Probe 1.添加文件 2.配置probe_com_cfg.h 2.1.选择接口 #define PROBE_COM_CFG_RS232_EN DEF_ENABLED /* Configure ...
- Java笔试面试题整理第七波
转载至:http://blog.csdn.net/shakespeare001/article/details/51388516 作者:山代王(开心阳) 1.super的作用 在Java中su ...
- 微信小程序版本管理
备忘录:<需要修改完善> 打开小程序开发者工具,点击版本管理,点击设置 , 通用更改码云的名字和邮箱 网络认证选择用户名和密码 把密码输入了,点击远程 添加 输入码云的https地址 和仓 ...
- leetcode297
public class Codec { // Encodes a tree to a single string. public string serialize(TreeNode root) { ...
- [java]给出一个字符串,将重复的字符去除,仅保留第一次出现的字符,且保持去重后的字符在原字符串中的顺序不变
- SQL 中的语法顺序与执行顺序
FROM : HOME SQL 是一种声明式语言 SQL 语言是为计算机声明了一个你想从原始数据中获得什么样的结果的一个范例,而不是告诉计算机如何能够得到结果. SQL 语言声明的是结果集的属性,计算 ...
- MYSQL性能优化(3)
优化数据库对象 1.优化表的数据类型 select * from tbl1 procedure analyse(16,256) ,会输出优化建议,结合情况优化 2.拆分表(仅Myisam) 2.1 纵 ...
- python,关于用户登录与注册问题
tag=Truecount=1while tag: name = input('请输入用户名>>:').strip() password = input('请输入密码>>:') ...
- hdu5698瞬间移动-(杨辉三角+组合数+乘法逆元)
瞬间移动 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...