Codeforces 1099
1099 E
题意
由'A','G','C','T'
组成的 \(n×m\) 的表格,有若干次操作,每次可以更改一个字母,问最少更改几次,使每个 \(2×2\) 的方框中都含有'A','G','C','T'
四个字母。只需输出更改完成后的表格。\((2≤n,m,n×m≤300000)\)
Examples
Input
2 2
AG
CT
Output
AG
CT
Input
3 5
AGCAG
AGCAG
AGCAG
Output
TGCAT
CATGC
TGCAT
解
首先明确如果一个表格是合法的,那要么它的每一行都是ABAB...的形式,要么它的每一列都是ABAB...的形式。
然后暴力枚举。
1099 F
题意
一棵树,每个节点有 \(a_i\) 块饼干。甲乙2人,轮流进行操作,甲先手。甲开始时在 \(1\) 号节点。
甲可以
- 花费 \(w_i\) 时间将自己移动到相邻的一个节点上;
- 花费 \(x_i\) 时间在节点 \(i\) 吃一块饼干。
乙可以
- 花费 \(0\) 时间切断甲所在节点和其某一子节点间的边。
有 \(T\) 秒时间,甲必须从原点出发,并且可以在任何时间停止游戏,一步一步回到原点,问最多可以吃多少片饼干。\((2≤n≤10^5,1≤T≤10^{18},1\le x_i\le 10^6,1\le t_i\le 10^6)\)
Examples
Input
5 26
1 5 1 7 7
1 3 2 2 2
1 1
1 1
2 0
2 0
Output
11
Input
3 179
2 2 1
6 6 6
1 3
2 3
Output
4
解
第一步,甲必定选择子树饼干数最大的一个子节点。
第二步~停止游戏前一步,甲必定选择子树饼干数次大的一个子节点。
接下来,注意到 \(t_i\) 只有 \(10^6\) ,于是考虑以吃一块饼干的时间为下标建一棵线段树,每个节点存储该时间能吃到的饼干数目和吃这么多饼干总共需要花费的时间。
询问函数传入剩余还有多少时间,返回这么多时间能吃的饼干数。
Code
#include<bits/stdc++.h>
#define maxn 100005
#define INF 100000000000000000ll
using namespace std;
typedef long long D;
template<typename tp>
void read(tp& x){
x=0;
char c=getchar();
bool sgn=0;
while((c<'0'||c>'9')&&c!='-')c=getchar();
if(c=='-')sgn=1,c=getchar();
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
if(sgn)x=-x;
}
template<typename tp>
void write(tp x){
if(x<0)putchar('-'),write(-x);
else{
if(x>=10)write(x/10);
putchar(x%10+'0');
}
}
struct edge{
D to,next,w;
}e[maxn<<1];
D head[maxn],cnte;
void add(D u,D v,D w){
e[++cnte].to=v;
e[cnte].w=w;
e[cnte].next=head[u];
head[u]=cnte;
}
D x[maxn],t[maxn],n,T,dp[maxn];
namespace SEG{
D tot[4000005],cnt[4000005];
void add(D p,D l,D r,D pos,D num){
if(l==r){
tot[p]+=pos*num;
cnt[p]+=num;
return;
}
D mid=(l+r)>>1;
if(pos<=mid)add(p<<1,l,mid,pos,num);
else add(p<<1|1,mid+1,r,pos,num);
tot[p]=tot[p<<1]+tot[p<<1|1];
cnt[p]=cnt[p<<1]+cnt[p<<1|1];
}
D query(D p,D l,D r,D restT){
if(tot[p]<=restT)return cnt[p];
if(l==r)return restT/l;
D mid=(l+r)>>1;
if(tot[p<<1]<=restT)return cnt[p<<1]+query(p<<1|1,mid+1,r,restT-tot[p<<1]);
else return query(p<<1,l,mid,restT);
}
}
void dfs(D u,D last,D restT){
SEG::add(1,1,1000000,t[u],x[u]);
dp[u]=SEG::query(1,1,1000000,restT);
D mx=-INF,mxi;
for(D i=head[u];i;i=e[i].next){
D v=e[i].to;
if(v==last)continue;
dfs(v,u,restT-(e[i].w<<1));
if(dp[v]>mx)mx=dp[v],mxi=v;
}
if(u==1){
dp[u]=max(dp[u],mx);
}
else{
D mx2=-INF;
for(D i=head[u];i;i=e[i].next){
D v=e[i].to;
if(v==last||v==mxi)continue;
mx2=max(mx2,dp[v]);
}
dp[u]=max(dp[u],mx2);
}
SEG::add(1,1,1000000,t[u],-x[u]);
}
signed main(){
read(n),read(T);
for(D i=1;i<=n;i++)read(x[i]);
for(D i=1;i<=n;i++)read(t[i]);
for(D i=2;i<=n;i++){
D u,w;
read(u),read(w);
add(i,u,w);
add(u,i,w);
}
dfs(1,0,T);
write(dp[1]);
return 0;
}