Codeforces 938C
/*
题解:
给定两个正整数n,m(m≤n),对于一个n阶0-1方阵,
其任意m阶子方阵中至少有一个元素“0”,则可以求解这个方阵中的“1”的最大数目。现求解这个问题的逆向问题:已知这个最大数目为X,求相应的n和m。
*/
#include
#include
#include
#include
#include
using namespace std;
int n,m;
int main()
{
int T;scanf("%d",&T);
while(T--)
{
int x;scanf("%d",&x);
if(x==0){printf("1 1\n");continue;}
bool bk=false;
for(int i=1;i*i<=x;i++)
{
int j=x/i;
if(i*j==x && ((i&1)==(j&1)))
{
n=(i+j)/2;
int temp=n-i;
if(temp==0)continue;
m=n/temp;
if(n>=m && (n/m)==temp)
{
printf("%d %d\n",n,m);
bk=true;
break;
}
}
}
if(bk==false)printf("-1\n");
}
return 0;
}
Codeforces 938D
/*
翻译:
给定一张包含n(n<=2*10^5)个节点的图,给出m(m<=2*10^5)条双向边,边有权,每个点也有权
对于每个点i,你要输出i到任意一个点再回来的最小代价,到达那个点时要加入那个点的点权,经过则不用
*/
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
LL d[210000];
struct pt
{
int x;
friend bool operator <(pt n1,pt n2){return d[n1.x]>d[n2.x];}
};
priority_queue q;
inline LL read()
{
LL f=1,x=0;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct node
{
LL c;
int x,y,next;
}a[810000];int len,last[210000];
void ins(int x,int y,LL c)
{
len++;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len;
}
int n,m,st;
bool v[210000];
int main()
{
n=read();m=read();st=n+1;
len=0;memset(last,0,sizeof(last));
for(int i=1;i<=m;i++)
{
int x=read(),y=read();LL c=read();
ins(x,y,2*c);ins(y,x,2*c);
}
for(int i=1;i<=n;i++)
{
LL x=read();
ins(st,i,x);
}
memset(d,63,sizeof(d));d[st]=0;
memset(v,false,sizeof(v));v[st]=true;
pt tmp;tmp.x=st;q.push(tmp);
while(!q.empty())
{
tmp=q.top();int x=tmp.x;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(d[y]>d[x]+a[k].c)
{
d[y]=d[x]+a[k].c;
if(v[y]==false)
{
v[y]=true;
pt cnt;cnt.x=y;q.push(cnt);
}
}
}
q.pop();v[x]=false;
}
for(int i=1;iprintf("%lld ",d[i]);
printf("%lld\n",d[n]);
return 0;
}
Codeforces 939E
/*
翻译:
给出Q(Q<=5*10^5)个操作,共有两种操作
第一种操作输入两个数op x:op表示第几种操作,x表示在当前序列中插入数x(x<=10^9),保证x大于当前序列中任意一个数
第二种操作输入一个数op:op表示第几种操作,求当前序列中的Maximize
定义Maximize为:在当前序列中找出一个子集,Maximize表示子集中数最大值/子集平均数的最大值
输出保留10位小数
*/
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
LL sum[510000],f[510000],list[510000];
int T,head;
int main()
{
head=0;
scanf("%d",&T);
while(T--)
{
int op;LL x;
scanf("%d",&op);
if(op==1)
{
scanf("%I64d",&list[++head]);
sum[head]=sum[head-1]+list[head];
}
else
{
int l=1,r=head;
while(l1)
{
int mid=(l+r)/2;
int mmid=(mid+r)/2;
if((double)(list[head]+sum[mid])/(mid+1)>(double)(list[head]+sum[mmid])/(mmid+1))l=mid;
else r=mmid;
}
if((double)(list[head]+sum[l])/(l+1)>(double)(list[head]+sum[r])/(r+1))printf("%.10lf\n",(double)list[head]-(double)(list[head]+sum[r])/(r+1));
else printf("%.10lf\n",(double)list[head]-(double)(list[head]+sum[l])/(l+1));
}
}
return 0;
}
Codeforces 940F
/*
翻译:
给出一个长度为n(n<=100000)的序列,序列中每个数a[i]<=10^9
设c[i]表示第i种数出现的次数
q(q<=100000)次询问,询问共有两种
第一种 1 x y 表示求序列中x~y c[i]的mex。mex表示最小的没有出现过的值(不包括0)
第二种 2 x y 表示把序列中第x位的数替换为y
*/
#include
#include
#include
#include
#include
#include
using namespace std;
map<int,int> q;
int val[210000],len;
int l,r,t;
struct pck{int p,c,las;}ch[210000];int chlen;
struct ask
{
int l,r,t,op;
}A[210000];int n,m,alen;
int block,pos[210000];
bool cmp(ask n1,ask n2)
{
if(pos[n1.l]!=pos[n2.l])return pos[n1.l]<pos[n2.l];
if(pos[n1.r]!=pos[n2.r])return pos[n1.r]<pos[n2.r];
return n1.tint vis[210000];//sum[i]的出现次数
int col[210000],las[210000],answer[210000],ans;//las[i]表示第i个位置上一次的颜色
int sum[210000];//每种数出现了多少次
void upd_col(int now,int c)
{
if(now>=l && now<=r)vis[sum[col[now]]]--,sum[col[now]]--,vis[sum[col[now]]]++;
col[now]=c;
if(now>=l && now<=r)vis[sum[col[now]]]--,sum[col[now]]++,vis[sum[col[now]]]++;
}
void del(int now)
{
vis[sum[col[now]]]--;
sum[col[now]]--;
vis[sum[col[now]]]++;
}
void add(int now)
{
vis[sum[col[now]]]--;
sum[col[now]]++;
vis[sum[col[now]]]++;
}
int gtans(){for(int i=1;;i++)if(vis[i]==0)return i;}
int main()
{
scanf("%d%d",&n,&m);
block=ceil(pow(n,2.0/3));
for(int i=1;i<=n;i++)pos[i]=(i-1)/block+1;
for(int i=1;i<=n;i++)
{
scanf("%d",&col[i]);
val[++len]=col[i];las[i]=col[i];
}
for(int i=1;i<=m;i++)
{
int op,u,v;
scanf("%d%d%d",&op,&u,&v);
if(op==1)
{
alen++;
A[alen].l=u;A[alen].r=v;A[alen].t=chlen;
A[alen].op=i-chlen;
}
else
{
chlen++;ch[chlen].p=u;ch[chlen].c=v;
ch[chlen].las=las[u];las[u]=v;
val[++len]=v;
}
}
sort(val+1,val+1+len);
len=unique(val+1,val+1+len)-val-1;
for(int i=1;i<=len;i++)q[val[i]]=i;
for(int i=1;i<=chlen;i++)ch[i].las=q[ch[i].las],ch[i].c=q[ch[i].c];
for(int i=1;i<=n;i++)col[i]=q[col[i]];
sort(A+1,A+1+alen,cmp);
l=A[1].l,r=A[1].r,t=A[1].t;
for(int i=1;i<=A[1].t;i++)col[ch[i].p]=ch[i].c;
for(int i=A[1].l;i<=A[1].r;i++)
{
vis[sum[col[i]]]--;
sum[col[i]]++;
vis[sum[col[i]]]++;
}
for(int i=1;;i++)if(vis[i]==0){answer[A[1].op]=i;break;}
for(int i=2;i<=alen;i++)
{
while(twhile(t>A[i].t)upd_col(ch[t].p,ch[t].las),t--;
while(lwhile(l>A[i].l)add(--l);
while(rwhile(r>A[i].r)del(r--);
answer[A[i].op]=gtans();
//for(int j=l;j<=r;j++)printf("%d ",col[j]);
}
for(int i=1;i<=alen;i++)printf("%d\n",answer[i]);
return 0;
}
Codeforces 946D
/*
翻译:
定义一个星期n(n<=500)天,一天m(m<=500)个小时。给定课表,你想翘课,但最多只能翘K(K<=500)节课
定义一天在学校的时间为(该天最后一节课时间-该天第一节课时间+1)
你想要这个星期呆在学校的时间尽量短,求这个最短时间
*/
#include
#include
#include
#include
#include
using namespace std;
char ch[510][510];
int sum[510][510];//第i天 翘j节课
int f[510][510];//前i天 翘j节课
int n,m,K,a[510],s[510],gt[510];
int pre[510];
int main()
{
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<=n;i++)
{
int cnt=0;
scanf("%s",ch[i]+1);
for(int j=1;j<=m;j++)a[j]=ch[i][j]-'0';
for(int j=1;j<=m;j++){if(a[j]==1)gt[++cnt]=j,s[i]++;}
if(cnt!=0)sum[i][0]=m-(gt[cnt]-gt[1]+1);
else {sum[i][0]=m;continue;}
for(int j=1;j<=s[i];j++)//翘多少节课
{
if(j==s[i]){sum[i][j]=m;break;}
int u=s[i]-j;//上多少节课
for(int k=1;k<=cnt-u+1;k++)
sum[i][j]=max(sum[i][j],m-(gt[k+u-1]-gt[k]+1));
}
}
f[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=K;j++)
for(int k=0;k<=min(K,s[i]);k++)
{
if(j>=k)f[i][j]=max(f[i-1][j-k]+sum[i][k],f[i][j]);
}
printf("%d\n",n*m-f[n][K]);
return 0;
}
Codeforces 946E
/*
翻译:
定义一个数为美丽数,当且仅当这个数长度为偶数,且他的某一个排列可以组成一个回文数
给出n(n<=2*10^100000),求小于n的最大美丽数
*/
#include
#include
#include
#include
#include
using namespace std;
char ch[210000];
int a[210000],g[15],len;
int f[210000][10];
void sol()
{
for(int i=len;i>=1;i--)
for(int j=a[i]-1;j>=0;j--)
{
if(i==1 && j==0)break;
int cnt=0,maxx=0;
for(int k=0;k<=9;k++)
{
int op=0;if(k==j)op=1;
if(f[i-1][k]^op==1)cnt++,maxx=k;
}
if(len-icontinue;
for(int k=1;k<=i-1;k++)printf("%d",a[k]);
printf("%d",j);
for(int k=i+1;k<=len-cnt;k++)printf("9");
int t=maxx;
for(int k=len-cnt+1;k<=len;k++)
{
int op=0;if(t==j)op=1;else op=0;
while(f[i-1][t]^op!=1){t--;if(t==j)op=1;else op=0;}
printf("%d",t);t--;
}
printf("\n");
return ;
}
for(int i=1;i2;i++)printf("9");
printf("\n");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(g,0,sizeof(g));
scanf("%s",ch+1);len=strlen(ch+1);
for(int i=1;i<=len;i++)a[i]=ch[i]-'0',g[a[i]]++;
if(len%2==1)
{
for(int i=1;iprintf("9");
printf("\n");continue;
}
if((g[1]==1 && g[0]==len-1 && a[1]==1) || (g[1]==2 && g[0]==len-2 && a[1]==1 && a[len]==1))
{
for(int i=1;i1;i++)printf("9");
printf("\n");continue;
}
for(int i=0;i<=9;i++)f[0][i]=0;//0 偶数次
for(int i=1;i<=len;i++)
for(int j=0;j<=9;j++)
{
if(a[i]==j)f[i][j]=f[i-1][j]^1;
else f[i][j]=f[i-1][j];
}
sol();
}
return 0;
}
Codeforces 946F
/*
翻译:
定义f[i]=f[i-1]+f[i-2],+表示拼接的意思,即为f[i-1]与f[i-2]拼接起来组成f[i]
给出一个子串(长度<=100),求这个子串在fn(n<=100)的**子序列**中出现了多少次
答案对1e9+7取模
*/
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
LL f[110][110][110];
LL lenth[110];//添加2^lenth[i]次方个数
char ch[110];int n,m;
int main()
{
scanf("%d%d",&n,&m);
scanf("%s",ch+1);
for(int i=1;i<=n;i++)f[ch[i]-'0'][i][i]=1;
lenth[0]=lenth[1]=2;
for(int i=2;i<=m;i++)lenth[i]=(lenth[i-1]*lenth[i-2])%mod;
for(int i=2;i<=m;i++)
for(int l=1;l<=n;l++)
for(int r=l;r<=n;r++)
{
LL opx,opy;
if(l==1)opx=lenth[i-1];else opx=1;
if(r==n)opy=lenth[i-2];else opy=1;
f[i][l][r]=(f[i][l][r]+(opx*f[i-2][l][r]+opy*f[i-1][l][r])%mod)%mod;
for(int k=l;k1][l][k]*f[i-2][k+1][r])%mod;
}
printf("%lld\n",f[m][1][n]);
return 0;
}
Codeforces 946G
/*
翻译:
给出一个长度为n(n<=10^5)的序列,要求最少的次数,使得序列变为一个删去一个数后严格上升的序列
*/
#include
#include
#include
#include
#include
using namespace std;
int f[2][210000];//没删 删
int n,pos,ans;
int main()
{
scanf("%d",&n);
memset(f,63,sizeof(f));
f[0][0]=-1e9;
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
int t=upper_bound(f[1]+1,f[1]+1+n,x-i+1)-f[1];
f[1][t]=x-i+1;ans=max(ans,t);
f[1][pos]=min(f[1][pos],f[0][pos]);ans=max(ans,pos);
t=upper_bound(f[0]+1,f[0]+1+n,x-i)-f[0];
f[0][pos=t]=x-i;
}
printf("%d\n",max(0,n-ans-1));
return 0;
}
Codeforces 950B
/*
翻译:
给出两个数字串a,b,长度分别为n,m(n,m<=10^6)
求之多能把a,b分成多少部分,使得每一部分分别相等
*/
#include
#include
#include
#include
#include
using namespace std;
int a[1100000],b[1100000];
int n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++)scanf("%d",&b[i]);
int i=0,j=0,sx=0,sy=0,ans=0;
while(i+1<=n && j+1<=m)
{
i++;j++;
sx+=a[i];sy+=b[j];
while(sx!=sy)
{
if(sxelse sy+=b[++j];
}
ans++;sx=sy=0;
}
printf("%d\n",ans);
return 0;
}
Codeforces 954A
/*
给定一段长度为n(n<=100)的字符串,R与U可以组合在一起,求组合在一起后最短字符串长度
*/
#include
#include
#include
#include
#include
using namespace std;
char ch[110];
int main()
{
int n;
scanf("%d",&n);
scanf("%s",ch+1);
int i=1,cnt=0;
while(i<=n)
{
if((ch[i]=='R' && ch[i+1]=='U') || (ch[i]=='U' && ch[i+1]=='R'))cnt++,i+=2;
else cnt++,i+=1;
}
printf("%d\n",cnt);
return 0;
}
Codeforces 954B
/*
翻译:
给定一个字符串,每次可以输入1个字符(低端操作)或进行之多一次高端操作
高端操作:复制当前字符串并插入至当前字符串末尾
求可以弄出这个字符串的最小总操作数
*/
#include
#include
#include
#include
#include
using namespace std;
char ch[110];
int n;
int main()
{
scanf("%d",&n);
scanf("%s",ch+1);
int ans=n;
for(int i=1;i<=n;i++)
{
bool bk=false;
for(int j=i+1;j<=i+i;j++)if(ch[j]!=ch[j-i]){bk=true;break;}
if(bk==false)ans=min(ans,n-2*i+1+i);
}
printf("%d\n",ans);
return 0;
}
Codeforces 954C
/*
翻译:
定义一个矩阵u*v由1~u*v组成,位置(i,j)填值(i-1)*v+j。每个格子可以向上下左右走(边界你懂得)
给出一段路线,判断这条路线是否可以在某一个矩阵中走出。不能输出NO,能则输出YES以及某个矩阵的u,v
*/
#include
#include
#include
#include
#include
using namespace std;
int n;
int a[210000];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(i==1)continue;
if(a[i]==a[i-1]){printf("NO\n");return 0;}
}
if(n==1)
{
printf("YES\n1 %d\n",a[1]);
return 0;
}
int x,y,t=1,sx=-1,sy=-1;
for(int i=2;i<=n;i++)if(abs(a[i]-a[i-1])!=1){sy=abs(a[i]-a[i-1]);break;}
if(sy==-1)
{
int maxx=0;
for(int i=1;i<=n;i++)maxx=max(maxx,a[i]);
printf("YES\n1 %d\n",maxx);
return 0;
}
x=(a[1]-1)/sy+1;y=(a[1]-1)%sy+1;
sx=max(sx,x);
bool bk=false;
while(t<=n)
{
t++;if(t>n)break;
if(a[t]==a[t-1]+1)
{
if(sy==-1 || yelse{bk=true;break;}
}
else if(a[t]==a[t-1]-1)
{
if(y==1){bk=true;break;}
else y--;
}
else
{
if(a[t]>a[t-1])
{
int tmp=a[t]-a[t-1];
if(sy==-1 || sy==tmp)sy=tmp;
else {bk=true;break;}
x++;
}
else
{
int tmp=a[t-1]-a[t];
if(sy==-1 || sy==tmp)sy=tmp;
else {bk=true;break;}
x--;
if(x==0){bk=true;break;}
}
}
sx=max(sx,x);
}
if(bk==true || (sx>1e9 || sy>1e9))printf("NO\n");
else printf("YES\n%d %d\n",sx,sy);
return 0;
}
Codeforces 954D
/*
翻译:
给出一张图,点数n(n<=1000),边数m(m<=1000)。
给出两个点s,t,要在图内新增一条边并保证s->t的最短路径长度不改变
求这样的边有多少条
*/
#include
#include
#include
#include
#include
using namespace std;
struct node
{
int x,y,next;
}a[2100];int len,last[1100];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int n,m,stx,sty;
bool v[1100];
int d[2][1100],list[1100],head,tail,st;
void spfa(int op)
{
memset(v,false,sizeof(v));v[st]=true;
memset(d[op],63,sizeof(d[op]));d[op][st]=0;
list[1]=st;head=1;tail=2;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(d[op][y]>d[op][x]+1)
{
d[op][y]=d[op][x]+1;
if(v[y]==false)
{
v[y]=true;
list[tail++]=y;
if(tail==n+1)tail=1;
}
}
}
head++;if(head==n+1)head=1;
v[x]=false;
}
}
bool mp[1100][1100];
int main()
{
scanf("%d%d%d%d",&n,&m,&stx,&sty);
memset(mp,false,sizeof(mp));len=0;memset(last,0,sizeof(last));
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);mp[x][y]=mp[y][x]=true;
ins(x,y);ins(y,x);
}
st=stx;spfa(0);
st=sty;spfa(1);
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)if(i!=j && mp[i][j]==false)
{
mp[i][j]=mp[j][i]=true;
if(d[0][i]+d[1][j]+1>=d[0][sty] && d[0][j]+d[1][i]+1>=d[0][sty])ans++;
}
printf("%d\n",ans);
return 0;
}
Codeforces 954E
/*
翻译:
给定n(n<=2*10^5)个水龙头,第i个水龙头有最大出水量a[i](a[i]<=10^6),且给定一个温度值t[i](t[i]<=10^6)。
定义一次出水得到的温度为Sigma(a[i]*t[i])/Sigama(a[i]),给定一次出水得到的温度,求最大总出水量。
如果得不到该温度,输出0
*/
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
int n,T;
struct node
{
LL a,t;
}P[1110000];
bool cmp(node n1,node n2){return n1.tint main()
{
scanf("%d%d",&n,&T);
for(int i=1;i<=n;i++)scanf("%lld",&P[i].a);
for(int i=1;i<=n;i++)scanf("%lld",&P[i].t);
LL sx=0,sy=0,ax=0,ay=0;
for(int i=1;i<=n;i++)
{
if(P[i].t>T)sx+=P[i].a*(P[i].t-T),ax+=P[i].a;
else if(P[i].tdouble ans=0;LL sum=0;
if(sx//负的多
{
ans=(double)ax;sum=sx;
sort(P+1,P+1+n,cmp);
int tmp=n;
for(int i=1;i<=n;i++)if(P[i].t>=T){tmp=i-1;break;}
for(int i=tmp;i>=1;i--)
{
if(sum-P[i].a*(T-P[i].t)>0)sum-=P[i].a*(T-P[i].t),ans+=(double)P[i].a;
else
{
ans+=(double)sum/(T-P[i].t);
sum=0;
break;
}
}
for(int i=1;i<=n;i++)if(P[i].t==T)ans+=(double)P[i].a;
if(sum==0)printf("%.15lf\n",ans);
else printf("0\n");
}
else
{
ans=(double)ay;sum=sy;
sort(P+1,P+1+n,cmp);
int tmp=1;
for(int i=n;i>=1;i--)if(P[i].t<=T){tmp=i+1;break;}
for(int i=tmp;i<=n;i++)
{
if(sum-P[i].a*(P[i].t-T)>0)sum-=P[i].a*(P[i].t-T),ans+=(double)P[i].a;
else
{
ans+=(double)sum/(P[i].t-T);
sum=0;
break;
}
}
for(int i=1;i<=n;i++)if(P[i].t==T)ans+=(double)P[i].a;
if(sum==0)printf("%.15lf\n",ans);
else printf("0\n");
}
return 0;
}
Codeforces 954F
/*
翻译:
给定一个3行m(m<=10^18)列的矩阵,从格子(i,j)可以移到(i,j+1)与(i-1(i>1),j+1),(i+1(i<3),j+1)
矩阵内会存在n个位于a[i]行,坐标l[i]~r[i]的障碍物,障碍物不能通行
求从格子(2,1)移动至(2,m)的方案数,答案对1e9+7取模
*/
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
struct node
{
LL l,r;int a;
}P[11000];
LL s[21000];
int t,c[5][41000],pre[5];
int n;LL m;
struct matrix
{
LL m[5][5];
matrix(){memset(m,0,sizeof(m));}
void cr(){m[1][1]=m[1][2]=m[2][1]=m[2][2]=m[2][3]=m[3][2]=m[3][3]=1;m[1][3]=m[3][1]=0;}
}tmp;
matrix mul(matrix u,matrix v,int n,int m,int p)
{
matrix ret;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=1;k<=p;k++)
ret.m[i][k]=(ret.m[i][k]+u.m[i][j]*v.m[j][k])%mod;
return ret;
}
matrix pow_mod(matrix u,LL b)
{
matrix ans;
if(b==0)return u;
for(int i=1;i<=3;i++)ans.m[i][i]=1;
while(b)
{
if(b%2==1)ans=mul(ans,u,3,3,3);
u=mul(u,u,3,3,3);b/=2;
}
return ans;
}
int main()
{
t=0;
scanf("%d%lld",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%lld%lld",&P[i].a,&P[i].l,&P[i].r);
s[++t]=P[i].l-1;s[++t]=P[i].r;
}
s[++t]=1;s[++t]=m;
sort(s+1,s+1+t);
t=unique(s+1,s+1+t)-s-1;
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
int l=lower_bound(s+1,s+1+t,P[i].l-1)-s;
int r=lower_bound(s+1,s+1+t,P[i].r)-s;
c[P[i].a][l]++;c[P[i].a][r]--;
}
matrix ans;
ans.m[1][1]=ans.m[1][3]=0;ans.m[1][2]=1;
memset(pre,0,sizeof(pre));
for(int u=1;ufor(int j=1;j<=3;j++)
{
pre[j]+=c[j][u];
if(pre[j])tmp.m[1][j]=tmp.m[2][j]=tmp.m[3][j]=0;
}
tmp=pow_mod(tmp,s[u+1]-s[u]);
ans=mul(ans,tmp,1,3,3);
}
printf("%lld\n",ans.m[1][2]);
return 0;
}
Codeforces 954G
/*
翻译:
给出一个长度为n的序列,给出值r,k,定义一个sum[i]表示i-r~i+r的和,共有值为k的数可以加入序列中的数里,求min(sum[i])的最大值
如给出长度为5的序列5 4 3 4 9,给定r=0,k=6
那么序列可以变为6 6 5 5 9,得出最优解min(sum[i])=5
1<=r<=n<=500000,k<=10^18
*/
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
LL k,a[510000],b[510000];
int n,r;
bool chk(LL p)
{
LL cnt=k,sum=0;
for(int i=1;i<=n;i++)b[i]=a[i];
for(int i=1;i<=1+r;i++)sum+=b[i];
int i=1;
while(i<=n)
{
if(sumif(u>cnt)return false;
b[min(n,i+r)]+=u;cnt-=u;sum=p;
}
if(i-r>=1)sum-=b[i-r];
if(i+1+r<=n)sum+=b[i+1+r];
i++;
}
return true;
}
int main()
{
scanf("%d%d%I64d",&n,&r,&k);
for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
LL l=0,r=(1LL<<63-1LL),ans;
while(l<=r)
{
LL mid=(l+r)/2;
if(chk(mid))ans=mid,l=mid+1;
else r=mid-1;
}
printf("%I64d\n",ans);
return 0;
}
Codeforces 955A
/*
翻译:
给猫喂食,初始饥饿值为H,每分钟增加饥饿值D。商店中每块面包售价cost,补充饥饿值N点。当时间大于等于20:00时售价打八折,求问能把猫喂饱的最少价格
*/
#include
#include
#include
#include
#include
using namespace std;
int hh,mm;
int H,D,N;
double cost;
int main()
{
scanf("%d%d",&hh,&mm);
scanf("%d%d%lf%d",&H,&D,&cost,&N);
double cx,cy;
double T;
if(H%N==0)T=(H/N);
else T=(H/N)+1;
if(hh<20)cx=cost*T;
else cx=cost*0.8*T;
int u=(60*(20-hh-1)+60-mm)*D+H;
if(u%N==0)T=(u/N);
else T=(u/N)+1;
if(hh<20)cy=cost*0.8*T;
printf("%.4lf\n",min(cx,cy));
return 0;
}
Codeforces 955B
/*
翻译:
给出一个串,要求判断这个串能否被拆分成两个部分,这两个部分可以被分成两种不同字母组成的串
*/
#include
#include
#include
#include
#include
using namespace std;
int tmp[110000],u[110000];
char ch[110000];
bool cmp(int n1,int n2){return n1>n2;}
int main()
{
scanf("%s",ch+1);int len=strlen(ch+1);
if(len<4){printf("No\n");return 0;}
for(int i=1;i<=len;i++)tmp[i]=ch[i]-'a'+1;
sort(tmp+1,tmp+1+len);
int T=0;
for(int i=2;i<=len;i++)if(tmp[i]!=tmp[i-1])T++;
if(T>3 || T==0){printf("No\n");return 0;}
if(T==3 || T==2){printf("Yes\n");return 0;}
//不同字符共 2个
int maxx=0;
for(int i=1;i<=len;i++)u[tmp[i]]++,maxx=max(maxx,tmp[i]);
sort(u+1,u+1+maxx,cmp);
if(u[1]==1 || u[2]==1)printf("No\n");
else printf("Yes\n");
return 0;
}
Codeforces 957A
/*
翻译:
给出一个可能未填满的串以及三种字符,相邻的两位不能填同样的字符,要求能否求出至少两种方案使得满足以上要求
*/
#include
#include
#include
#include
#include
using namespace std;
char ch[110];
int main()
{
int n;
scanf("%d",&n);
scanf("%s",ch+1);
bool bk=true;bool bkk=false;
for(int i=1;iif(ch[i]==ch[i+1] && ch[i]!='?'){bk=false;break;}
if(bk==false){printf("No\n");return 0;}
for(int i=1;i<=n;i++)if(ch[i]=='?')bkk=true;
if(bkk==false){printf("No\n");return 0;}
for(int i=1;iif(ch[i]==ch[i+1] && ch[i]=='?'){bk=false;break;}
if(bk==false){printf("Yes\n");return 0;}
for(int i=1;i<=n;i++)if(ch[i]=='?' && (ch[i-1]==ch[i+1] || i==1 || i==n)){bk=false;break;}
if(bk==false)printf("Yes\n");
else printf("No\n");
return 0;
}