9.2
P9755
我们可以对最少天数进行二分答案
然后通过数学方法求出每个节点的最晚达到时间,记为 \(t[i]\)
然后采用贪心的思想,肯定要先去处理 \(t[i]\) 最大的节点
从该节点一直往上跳,直到遇到已经种过树的节点
当然路过的节点也都应该进行标记,后面碰到就不需要求了
注意进行数学计算时会超 \(long long\) 需要开 \(\_\_int128\)
这类题目还是很讲究细节的,写代码的时候全程不能分神啊
CODE
#include<bits/stdc++.h>
#define fst first
#define sec second
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef __int128 LL;
typedef pair<int,int> pii;
const int maxn=1e5+5;
const int inf=1e9+1;
void read(int& x){
char c;
bool f=0;
while((c=getchar())<48) f|=(c==45);
x=c-48;
while((c=getchar())>47) x=(x<<3)+(x<<1)+c-48;
x=(f ? -x : x);
}
void read(LL& x){
char c;
bool f=0;
while((c=getchar())<48) f|=(c==45);
x=c-48;
while((c=getchar())>47) x=(x<<3)+(x<<1)+c-48;
x=(f ? -x : x);
}
int head[maxn],nxt[maxn<<1],e[maxn<<1];
int mp_cnt;
int f[maxn];
pii t[maxn];
bool vis[maxn];
LL a[maxn],b[maxn],c[maxn],lim[maxn];//lim不取1的末尾
int n;
void init_mp(){
memset(head,-1,sizeof(head));
mp_cnt=-1;
}
void add_edge(int u,int v){
e[++mp_cnt]=v;
nxt[mp_cnt]=head[u];
head[u]=mp_cnt;
}
void dfs(int u,int fa){
f[u]=fa;
for(int i=head[u];~i;i=nxt[i]){
int v=e[i];
if(v==fa) continue;
dfs(v,u);
}
}
LL cal(int id,int l,int r){
if(l>lim[id]) return r-l+1;
else if(r>lim[id]) return r-lim[id]+cal(id,l,lim[id]);
else return (LL)(r-l+1)*b[id]+(LL)(l+r)*(r-l+1)*c[id]/2;
}
bool check(int p){
for(int i=1;i<=n;i++){
int l=1,r=p,ans=-1;
while(l<=r){
int mid=(l+r)>>1;
if(cal(i,mid,p)>=a[i]) ans=mid,l=mid+1;
else r=mid-1;
}
if(ans<0) return false;
t[i].fst=ans,t[i].sec=i;
vis[i]=0;
}
sort(t+1,t+n+1);
vis[1]=1;
int d=1;
for(int i=1;i<=n;i++){
if(vis[t[i].sec]) continue;
if(t[i].fst<d) return false;
int u=t[i].sec;
while(!vis[u]){
++d;
vis[u]=1;
u=f[u];
}
if(t[i].fst<d) return false;
}
return true;
}
int main(){
read(n);
for(int i=1;i<=n;i++){
read(a[i]),read(b[i]),read(c[i]);
if(c[i]<0){
if(b[i]%c[i]) lim[i]=-b[i]/c[i];
else lim[i]=-b[i]/c[i]-1;
}
else lim[i]=inf;
}
init_mp();
int u,v;
for(int i=1;i<n;i++){
read(u),read(v);
add_edge(u,v),add_edge(v,u);
}
dfs(1,0);
int l=n,r=inf,ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
printf("%d",ans);
return 0;
}
//^o^
P7914
贴个代码,今天马上结束了
CODE
#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
const int mod=1e9+7;
const int maxn=505;
void read(int& x){
char c;
bool f=0;
while((c=getchar())<48) f|=(c==45);
x=c-48;
while((c=getchar())>47) x=(x<<3)+(x<<1)+c-48;
x=(f ? -x : x);
}
LL dp[maxn][maxn][6];
//0:全是* 1:左右两个相互匹配的括号 2:左边括号,右边*
//3:左右两个不匹配的括号 4:左边*,右边括号 5:两边全是*
char c[maxn];
int n,k;
int main(){
read(n),read(k);
scanf("%s",c+1);
for(int i=1;i<=n;i++) dp[i][i-1][0]=1;
for(int len=1;len<=n;len++){
for(int l=1,r=len;r<=n;l++,r++){
if(len<=k) dp[l][r][0]=dp[l][r-1][0]&(c[r]=='?'||c[r]=='*');
if(len>=2){
for(int i=l;i<r;i++){
if((c[l]=='?'||c[l]=='(')&&(c[r]=='?'||c[r]==')')){
dp[l][r][1]=dp[l+1][r-1][0]+dp[l+1][r-1][2]+dp[l+1][r-1][3]+\
dp[l+1][r-1][4];
dp[l][r][1]%=mod;
}
dp[l][r][2]+=dp[l][i][3]*dp[i+1][r][0]%mod,dp[l][r][2]%=mod;
dp[l][r][3]+=(dp[l][i][2]+dp[l][i][3])*dp[i+1][r][1]%mod;
dp[l][r][4]+=(dp[l][i][4]+dp[l][i][5])*dp[i+1][r][1]%mod;
dp[l][r][3]%=mod,dp[l][r][4]%=mod;
dp[l][r][5]+=dp[l][i][4]*dp[i+1][r][0]%mod,dp[l][r][5]%=mod;
}
}
dp[l][r][5]=(dp[l][r][5]+dp[l][r][0])%mod;
dp[l][r][3]=(dp[l][r][3]+dp[l][r][1])%mod;
}
}
printf("%lld",dp[1][n][3]);
return 0;
}
//^o^

浙公网安备 33010602011771号