一、A. Optimal Path
最优一定是先到最左再向下
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pr;
const int inf =0x3f3f3f3f;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define in freopen("in.txt","r",stdin)
#define out freopen("out.txt","w",stdout)
#define ms(x,a) memset(x,a,sizeof(x))
#define ll long long
#define pb push_back
#define pr pair<int,int>
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define rg register int//卡常
#define ONLINE_JUDGE
const int mod=1e9+7;
const int maxn=2e5+10;
const int maxe=1e6+5;
int n,m,a[maxn];
void solve()
{
scanf("%d%d",&n,&m);
ll sum=1ll*(m+1)*m/2;
sum+=(m+1ll*n*m)*n/2;
printf("%lld\n",sum-m);
}
int main()
{
int t=1;
scanf("%d",&t);
while(t--){
solve();
}
return 0;
}
二、B. Palindromic Numbers
不用想太复杂,第一位不为9的情况下,全部变成
99...9
9
n
99...99_n
99...99n即可
第一位为9的情况下,变成
11...1
1
n
+
1
11...11_{n+1}
11...11n+1,n+1个1即可
因为要位数相同
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pr;
const int inf =0x3f3f3f3f;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define in freopen("in.txt","r",stdin)
#define out freopen("out.txt","w",stdout)
#define ms(x,a) memset(x,a,sizeof(x))
#define ll long long
#define pb push_back
#define pr pair<int,int>
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define rg register int//卡常
#define ONLINE_JUDGE
const int mod=1e9+7;
const int maxn=1e5+10;
const int maxe=1e6+5;
int n,m;
char a[maxn];
char tmp;
void solve()
{
scanf("%d",&n);
scanf("%s",a+1);
char ans[maxn];
ll sum=0;
if((a[1]-'0')!=9){
for(int i=1;i<=n;i++){
ans[i]=9-(a[i]-'0')+'0';
}
}else{
bool f=false;
if(a[n]=='1') ans[n]='0';
else if(a[n]!='0')ans[n]=11-(a[n]-'0')+'0',f=true;
else ans[n]='1';
for(int i=n-1;i>=1;i--){
if(a[i]=='1'){
if(f){
ans[i]='9';f=true;
}else{
ans[i]='0';f=false;
}
}
else if(a[i]=='0'){
if(f){
ans[i]='0';f=false;
}else{
ans[i]='1';f=false;
}
}
else{
if(f){
ans[i]=10-(a[i]-'0')+'0';
}else{
ans[i]=11-(a[i]-'0')+'0';
}
f=true;
}
}
}
for(int i=1;i<=n;i++) printf("%c",ans[i]);
printf("\n");
}
int main()
{
int t=1;
scanf("%d",&t);
while(t--){
solve();
}
return 0;
}
三、C. Helping the Nature
看上去就像是数据结构,拿差分数组,不一样的差分本质上都是一样的
3种办法对应的是
- d 1 d_1 d1 - 1, d i + 1 d_{i+1} di+1 + 1
- d i d_i di - 1
- d 1 d_1 d1 + 1
只有3能让
d
1
d_1
d1 增加,其余的只能减少,可以先解决其他位置后在考虑
d
1
d_1
d1
从原数组意义上来说就是先把所有的数字变成一样的,然后统一操作到0
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pr;
const int inf =0x3f3f3f3f;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define in freopen("in.txt","r",stdin)
#define out freopen("out.txt","w",stdout)
#define ms(x,a) memset(x,a,sizeof(x))
#define ll long long
#define pb push_back
#define pr pair<int,int>
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define rg register int//卡常
#define ONLINE_JUDGE
const int mod=1e9+7;
const int maxn=2e5+10;
const int maxe=1e6+5;
int n,m;ll a[maxn];
void solve()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
if(a[n]>0 || a[1]<0){
printf("No\n");return;
}
ll adds=-a[n];
for(int i=n-1;i>1;i--){
if(a[i]>adds){
printf("No\n");return;
}
ll oldadds=adds;
adds=adds-a[i];
if(oldadds!=0 && adds==0){
printf("No\n");return;
}
}
if(a[1]==adds) printf("Yes\n");
else printf("No\n");
}
int main()
{
int t=1;
scanf("%d",&t);
while(t--){
solve();
}
return 0;
}
四、D. River Locks
一眼二分
首先肯定是开阀门从前往后开是最优的,因为后面开的阀门可能会浪费,而且第一个水池只能由第一个阀门灌满
我第一反应是DP,从i开始考虑,i-1个阀门填满需要的时间退出i个阀门的时间,然后看到了其他人的解,简单的数学运算发现
⌈
∑
i
n
v
i
i
⌉
\lceil \frac{ \sum_i^n {v_i} } {i} \rceil
⌈i∑invi⌉
就是填满需要的时间
O(nlogn)可以过,二分找时间即可
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pr;
const int inf =0x3f3f3f3f;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define in freopen("in.txt","r",stdin)
#define out freopen("out.txt","w",stdout)
#define ms(x,a) memset(x,a,sizeof(x))
#define ll long long
#define pb push_back
#define pr pair<int,int>
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define rg register int//卡常
#define ONLINE_JUDGE
const int mod=1e9+7;
const int maxn=2e5+10;
const int maxe=1e6+5;
int n,m;ll a[maxn];
vector<int> edge[maxn];
int fa[maxn],d[maxn];
ll num[maxn];
ll lr[maxn][2];
ll ans=0;
void bfs()
{
ms(num,0);
queue<int> q;
for(int i=1;i<=n;i++){
if(d[i]==0) q.push(i);
}
ans=0;
while(!q.empty()){
int u=q.front();
q.pop();
if(u==0)continue;
if(num[u]<lr[u][0]){
num[fa[u]]+=lr[u][1];
ans++;
}else{
num[fa[u]]+=min(lr[u][1],num[u]);
}
d[fa[u]]--;
if(!d[fa[u]]) q.push(fa[u]);
}
}
void solve()
{
scanf("%d",&n);
int t;
ms(d,0);
for(int i=1;i<n;i++){
scanf("%d",&t);
edge[t].pb(i+1);
fa[i+1]=t;
d[t]++;
}
for(int i=1;i<=n;i++){
scanf("%lld %lld",&lr[i][0],&lr[i][1]);
}
bfs();
printf("%lld\n",ans);
for(int i=1;i<=n;i++){
edge[i].clear();
}
}
int main()
{
int t=1;
scanf("%d",&t);
while(t--){
solve();
}
return 0;
}